using System.Text.Json; using System.Text.Json.Serialization; using YandexMusic.API.Models.Pins.Items; namespace YandexMusic.API.Models.Pins; /// Конвертер для закреплённых объектов (пинов). Десериализует в конкретные типы на основе поля type. public class YPinConverter : JsonConverter> { public override List Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.StartArray) throw new JsonException("Ожидается массив пинов"); var pins = new List(); while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndArray) break; if (reader.TokenType != JsonTokenType.StartObject) throw new JsonException("Ожидается объект пина"); using var doc = JsonDocument.ParseValue(ref reader); var root = doc.RootElement; var typeProp = root.GetProperty("type"); var typeStr = typeProp.GetString(); if (!Enum.TryParse(typeStr, true, out var pinType)) throw new JsonException($"Неизвестный тип пина: {typeStr}"); YPin? pin = null; var rawText = root.GetRawText(); switch (pinType) { case YPinType.Album: pin = JsonSerializer.Deserialize>(rawText, options); break; case YPinType.Artist: pin = JsonSerializer.Deserialize>(rawText, options); break; case YPinType.Playlist: pin = JsonSerializer.Deserialize>(rawText, options); break; case YPinType.Wave: pin = JsonSerializer.Deserialize>(rawText, options); break; default: pin = JsonSerializer.Deserialize(rawText, options); break; } if (pin != null) pins.Add(pin); } return pins; } public override void Write(Utf8JsonWriter writer, List value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value, options); } }