using System.Collections; using static LinqToDB.Reflection.Methods.LinqToDB.Insert; namespace Pf2e.Web.Helpers.Format; /// /// Абстрактный класс форматтера значений. /// public abstract class ValueFormatter { /// /// Проверяет, может ли форматтер обработать указанный тип. /// /// Тип значения. /// true, если форматтер может обработать тип, иначе false. public abstract bool CanFormat(Type type); /// /// Форматирует значение для отображения. /// /// Значение для форматирования. /// Строковое представление отформатированного значения. public abstract string Format(object value); /// /// Форматирует имя типа для отображения. /// /// Тип значения. /// Строковое представление имени типа. public virtual string TypeName(Type type) => type.Name; } /// /// Форматтер для конкретного типа. /// /// Тип значения. /// Функция форматирования значения. public class TypeValueFormatter(Func formatter) : ValueFormatter { public override bool CanFormat(Type type) => type == typeof(T); public override string Format(object value) => formatter(value); } /// /// Форматтер с пользовательскими функциями проверки и форматирования. /// /// Функция проверки типа. /// Функция форматирования значения. public class CustomValueFormatter( Func checker, Func formatter, Func? typeName = null ) : ValueFormatter { public override bool CanFormat(Type type) => checker(type); public override string Format(object value) => formatter(value); public override string TypeName(Type type) => typeName?.Invoke(type) ?? base.TypeName(type); } /// /// Форматтер для коллекций. /// public class CollectionFormatter() : ValueFormatter { public override bool CanFormat(Type type) => typeof(IEnumerable).IsAssignableFrom(type) && type != typeof(string); public override string Format(object value) { IEnumerable collection = (IEnumerable)value; List items = []; foreach (object? item in collection) { items.Add(Formatters.Format(item)); } return items.Count == 0 ? "(empty)" : string.Join("
", items); } public override string TypeName(Type type) { return $"{type.Name[..^2]}<{string.Join(", ", type.GetGenericArguments().Select(t => t.Name))}>"; } }