using System.Text.Json; using System.Text.Json.Serialization; using YandexMusic.API.Models.Feed.Event; namespace YandexMusic.API.Models.Feed; /// Конвертер для событий ленты (десериализация в конкретные типы на основе поля type). public class YFeedEventConverter : JsonConverter> { public override List Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.StartArray) throw new JsonException("Ожидается массив событий"); var events = 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; // Определяем тип события: может быть в поле "typeForFrom" или "type" var typeToken = root.TryGetProperty("typeForFrom", out var tf) ? tf : (root.TryGetProperty("type", out var t) ? t : throw new JsonException("Не найден тип события")); var typeStr = typeToken.GetString(); if (!Enum.TryParse(typeStr, true, out var eventType)) throw new JsonException($"Неизвестный тип события: {typeStr}"); YFeedEventTitled? feedEvent = null; var rawText = root.GetRawText(); switch (eventType) { case YFeedEventType.GenreTop: feedEvent = JsonSerializer.Deserialize(rawText, options); break; case YFeedEventType.NewAlbums: feedEvent = JsonSerializer.Deserialize(rawText, options); break; case YFeedEventType.NewAlbumsOfFavoriteGenre: feedEvent = JsonSerializer.Deserialize(rawText, options); break; case YFeedEventType.Notification: feedEvent = JsonSerializer.Deserialize(rawText, options); break; case YFeedEventType.Promotion: feedEvent = JsonSerializer.Deserialize(rawText, options); break; case YFeedEventType.RecentTrackLikeToTracks: feedEvent = JsonSerializer.Deserialize(rawText, options); break; case YFeedEventType.RecommendedArtistsWithArtistsFromHistory: feedEvent = JsonSerializer.Deserialize(rawText, options); break; case YFeedEventType.RecommendedSimilarArtists: feedEvent = JsonSerializer.Deserialize(rawText, options); break; case YFeedEventType.RecommendedSimilarGenre: feedEvent = JsonSerializer.Deserialize(rawText, options); break; case YFeedEventType.MissedTracksByArtist: case YFeedEventType.RareArtist: case YFeedEventType.RecommendedTracksByArtistFromHistory: feedEvent = JsonSerializer.Deserialize(rawText, options); break; case YFeedEventType.NewTracksOfFavoriteGenre: case YFeedEventType.TracksByGenre: feedEvent = JsonSerializer.Deserialize(rawText, options); break; case YFeedEventType.WellForgottenOldArtists: feedEvent = JsonSerializer.Deserialize(rawText, options); break; case YFeedEventType.NeverHeardFromLibrary: case YFeedEventType.WellForgottenOldTracks: feedEvent = JsonSerializer.Deserialize(rawText, options); break; default: feedEvent = JsonSerializer.Deserialize(rawText, options); break; } if (feedEvent != null) events.Add(feedEvent); } return events; } public override void Write(Utf8JsonWriter writer, List value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value, options); } }