using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace pkNX.Structures;
public static class TableUtil
{
///
/// Converts an enumerable list of to a tab separated sheet.
///
/// Object Type
/// Array of type T
/// 2 dimensional sheet of cells
public static string GetTable(IEnumerable arr) where T : notnull => string.Join(Environment.NewLine, GetTableRaw(arr));
private const char sep = '\t';
private static IEnumerable GetTableRaw(IEnumerable arr) where T : notnull
=> Table(arr).Select(row => string.Join(sep, row));
private static IEnumerable GetTableRaw(IEnumerable arr, Type t) where T : notnull
=> Table(arr, t).Select(row => string.Join(sep, row));
public static string GetNamedTable(IEnumerable arr, IList names, string? name = null) where T : notnull
{
var list = GetTableRaw(arr).ToArray();
// slap in name to column header
list[0] = $"Index{sep}{name ?? typeof(T).Name}{sep}{list[0]}";
// slap in row name to row
for (int i = 1; i < list.Length; i++)
list[i] = $"{i - 1}{sep}{names[i - 1]}{sep}{list[i]}";
return string.Join(Environment.NewLine, list);
}
public static string GetNamedTypeTable(IList arr, IList names, string? name = null) where T : notnull
{
var t = arr[0].GetType();
if (t.Name.StartsWith("tableReader_")) // FlatBuffer generated wrapper
t = t.BaseType;
if (t is null)
throw new ArgumentException("Type is null");
var list = GetTableRaw(arr, t).ToArray();
// slap in name to column header
list[0] = $"Index{sep}{name ?? t.Name}{sep}{list[0]}";
// slap in row name to row
for (int i = 1; i < names.Count + 1; i++)
list[i] = $"{i - 1}{sep}{names[i - 1]}{sep}{list[i]}";
return string.Join(Environment.NewLine, list);
}
private static IEnumerable> Table(IEnumerable arr) where T : notnull
{
var type = typeof(T);
yield return GetNames(type);
foreach (var z in arr)
yield return GetValues(z, type);
}
private static IEnumerable> Table(IEnumerable arr, Type type) where T : notnull
{
yield return GetNames(type);
foreach (var z in arr)
yield return GetValues(z, type);
}
private static IEnumerable GetNames(Type type)
{
foreach (var z in type.GetProperties())
yield return z.Name;
foreach (var z in type.GetFields())
yield return z.Name;
}
private static IEnumerable GetValues(object obj, Type type)
{
foreach (var z in type.GetProperties())
yield return GetFormattedString(z.GetValue(obj, null));
foreach (var z in type.GetFields())
yield return GetFormattedString(z.GetValue(obj));
}
private static string GetFormattedString(object? obj)
{
if (obj == null)
return string.Empty;
if (obj is ulong u)
return u.ToString("X16");
if (obj is IEnumerable x and not string)
return string.Join('|', JoinEnumerator(x.GetEnumerator()).Select(GetFormattedString));
var objType = obj.GetType();
if (objType.IsEnum)
return obj.ToString() ?? string.Empty;
var mi = objType.GetMethods().First(z => z.Name == nameof(obj.ToString));
if (mi.DeclaringType == objType)
return obj.ToString() ?? string.Empty;
var props = objType.GetProperties().Select(z => GetFormattedString(z.GetValue(obj)));
var fields = objType.GetFields().Select(z => GetFormattedString(z.GetValue(obj)));
return string.Join('|', props.Concat(fields));
}
private static IEnumerable