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);
}
}