using System.ComponentModel; using Pf2e.Database.Model; using Pf2e.Database.Model.Base.Keywords; using Pf2e.Database.Model.Base.Source; using Pf2e.Database.Model.Base.Targets; using Pf2e.Database.Model.Common.I18n; using Pf2e.Database.Model.Enum; namespace Pf2e.Web.Helpers.Format; public static class Formatters { /// /// Форматтер для перечислений (enum). /// public static readonly ValueFormatter EnumFormatter = new CustomValueFormatter( (type) => type.IsEnum, (value) => { Enum enumValue = (Enum)value; string description = GetEnumDescription(enumValue); return $"{description} ({enumValue})"; string GetEnumDescription(Enum v) { Type type = v.GetType(); string name = Enum.GetName(type, v) ?? v.ToString(); System.Reflection.FieldInfo? field = type.GetField(name); if (field == null) return v.ToString(); if ( Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) is DescriptionAttribute attr ) { return attr.Description; } return v.ToString(); } } ); /// /// Форматтер для примитивных типов и строк. /// public static readonly ValueFormatter PrimitiveFormatter = new CustomValueFormatter( (type) => type.IsPrimitive || type == typeof(string) || type == typeof(decimal), (value) => value.ToString() ?? "null" ); /// /// Форматтер для коллекций. /// public static readonly ValueFormatter CollectionFormatter = new CollectionFormatter(); /// /// Форматтеры для стандартных типов из базы данных. /// public static readonly List DefaultTypeFormatters = [ new TypeValueFormatter( (value) => { LocaleString localeString = (LocaleString)value; List items = []; foreach (LocaleItem item in localeString) { items.Add($"{item.Locale}: {item.Value}"); } return string.Join("
", items); } ), // IEntity new CustomValueFormatter( (type) => typeof(IEntity).IsAssignableFrom(type), (value) => { IEntity entity = (IEntity)value; EntityType entityType = entity.Entity.Type; string typeName = PgNameHelper.GetPgName(entityType); string slug = entity.Entity.Slug; string name = entity.Entity.Name[LocaleType.English]; return $"{name}"; } ), // EntitySource new TypeValueFormatter( (value) => { EntitySource entitySource = (EntitySource)value; string sourceName = entitySource.Source.Name; string suffix = !string.IsNullOrEmpty(entitySource.Suffix) ? $" ({entitySource.Suffix})" : ""; string isRemaster = entitySource.IsRemaster ? " [Remaster]" : ""; return $"{sourceName}{suffix}{isRemaster}"; } ), // Keyword new TypeValueFormatter( (value) => { Keyword keyword = (Keyword)value; string name = keyword.Name[LocaleType.English]; return $"{name}"; } ), // KeywordAlias new TypeValueFormatter( (value) => { KeywordAlias alias = (KeywordAlias)value; return $"{alias.Value}"; } ), // ExternalTarget new TypeValueFormatter( (value) => { ExternalTarget target = (ExternalTarget)value; return $"{target.Name} (Icon: {target.Icon}, Prefix: {target.Prefix})"; } ), // EntityExternal new TypeValueFormatter( (value) => { EntityExternal entityExternal = (EntityExternal)value; string targetName = entityExternal.Target?.Name ?? "Unknown"; string externalId = !string.IsNullOrEmpty(entityExternal.ExternalId) ? $" ID: {entityExternal.ExternalId}" : ""; string suffix = !string.IsNullOrEmpty(entityExternal.Suffix) ? $" Suffix: {entityExternal.Suffix}" : ""; return $"{targetName}{externalId}{suffix}"; } ), // Source new TypeValueFormatter( (value) => { Source source = (Source)value; string releaseDate = source.ReleaseDate?.ToString("yyyy-MM-dd") ?? "Unknown"; return $"{source.Name} (Category: {source.Category}, Release: {releaseDate})"; } ), ]; /// /// Набор всех стандартных форматтеров. /// public static readonly List AllFormatters = [ .. DefaultTypeFormatters, EnumFormatter, PrimitiveFormatter, CollectionFormatter, ]; /// /// Добавить пользовательский форматтер в набор всех форматтеров. /// /// Добавляемый форматтер. public static void AddFormatter(ValueFormatter formatter) { AllFormatters.Insert(0, formatter); } /// /// Выбрать подходящий форматтер для типа. /// /// Тип значения. /// Форматтер для типа или null, если подходящего не найдено. public static ValueFormatter? SelectFormatter(Type type) => AllFormatters.FirstOrDefault(f => f.CanFormat(type)) ?? null; /// /// Выбрать подходящий форматтер для значения. /// /// Значение. /// Форматтер для значения или null, если значение равно null или подходящего не найдено. public static ValueFormatter? SelectFormatter(object? value) => value == null ? null : SelectFormatter(value.GetType()); /// /// Форматировать значение в строку. /// /// Форматируемое значение. /// Строковое представление отформатированного значения. public static string Format(object? value) => SelectFormatter(value)?.Format(value!) ?? "[not implemented]"; }