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