diff --git a/YandexMusic.API/Extensions/EnumHelper.cs b/YandexMusic.API/Extensions/EnumHelper.cs new file mode 100644 index 0000000..95624f3 --- /dev/null +++ b/YandexMusic.API/Extensions/EnumHelper.cs @@ -0,0 +1,49 @@ +using System.Collections.Concurrent; +using System.Reflection; +using System.Runtime.Serialization; + +namespace YandexMusic.API.Extensions; + +public static class EnumHelper +{ + private static readonly ConcurrentDictionary> _enumMaps = new(); + + /// + /// Пытается преобразовать строковое значение в enum с учётом атрибутов [EnumMember]. + /// + /// Тип enum + /// Строковое значение из JSON или другого источника + /// Учитывать регистр (по умолчанию true) + /// Результат преобразования, если успешно, иначе default + /// true если преобразование удалось, иначе false + public static bool TryEnumFromMemberValue(string memberValue, bool ignoreCase, out T result) where T : struct, Enum + { + result = default; + if (string.IsNullOrEmpty(memberValue)) + return false; + + var type = typeof(T); + // Получаем или создаём кэш для данного enum + var map = _enumMaps.GetOrAdd(type, t => + { + var dict = new Dictionary(ignoreCase ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal); + foreach (var field in t.GetFields(BindingFlags.Static | BindingFlags.Public)) + { + var attr = field.GetCustomAttribute(); + var key = attr?.Value ?? field.Name; + dict[key] = field.GetValue(null)!; + } + return dict; + }); + + // Ищем по кэшу + if (map.TryGetValue(memberValue, out var value)) + { + result = (T)value; + return true; + } + + // fallback на обычный Enum.TryParse (без учёта EnumMember) + return Enum.TryParse(memberValue, ignoreCase, out result); + } +} \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/YLandingEntityConverter.cs b/YandexMusic.API/Models/Landing/Entity/YLandingEntityConverter.cs index 2f1e0e1..d672621 100644 --- a/YandexMusic.API/Models/Landing/Entity/YLandingEntityConverter.cs +++ b/YandexMusic.API/Models/Landing/Entity/YLandingEntityConverter.cs @@ -1,5 +1,6 @@ using System.Text.Json; using System.Text.Json.Serialization; +using YandexMusic.API.Extensions; using YandexMusic.API.Models.Landing.Entity.Entities; namespace YandexMusic.API.Models.Landing.Entity; @@ -26,7 +27,8 @@ public class YLandingEntityConverter : JsonConverter> var typeProp = root.GetProperty("type"); var typeStr = typeProp.GetString(); - if (!Enum.TryParse(typeStr, true, out var entityType)) + + if (!EnumHelper.TryEnumFromMemberValue(typeStr, true, out var entityType)) throw new JsonException($"Неизвестный тип сущности: {typeStr}"); YLandingEntity? entity = null;