using System; using System.Collections.Generic; using System.ComponentModel; using System.Text.Json; using System.Text.Json.Serialization; namespace Jellyfin.Extensions.Json.Converters { /// /// Convert delimited string to array of type. /// /// Type to convert to. public abstract class JsonDelimitedCollectionConverter : JsonConverter> { private readonly TypeConverter _typeConverter; /// /// Initializes a new instance of the class. /// protected JsonDelimitedCollectionConverter() { _typeConverter = TypeDescriptor.GetConverter(typeof(T)); } /// /// Gets the array delimiter. /// protected virtual char Delimiter { get; } /// public override IReadOnlyCollection? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { // null got handled higher up the call stack var stringEntries = reader.GetString()!.Split(Delimiter, StringSplitOptions.RemoveEmptyEntries); if (stringEntries.Length == 0) { return []; } var typedValues = new List(); for (var i = 0; i < stringEntries.Length; i++) { try { var parsedValue = _typeConverter.ConvertFromInvariantString(stringEntries[i].Trim()); if (parsedValue is not null) { typedValues.Add((T)parsedValue); } } catch (FormatException) { // Ignore unconvertible inputs } } if (typeToConvert.IsArray) { return typedValues.ToArray(); } return typedValues; } return JsonSerializer.Deserialize(ref reader, options); } /// public override void Write(Utf8JsonWriter writer, IReadOnlyCollection? value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value, options); } } }