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 JsonDelimitedArrayConverter : JsonConverter { private readonly TypeConverter _typeConverter; /// /// Initializes a new instance of the class. /// protected JsonDelimitedArrayConverter() { _typeConverter = TypeDescriptor.GetConverter(typeof(T)); } /// /// Gets the array delimiter. /// protected virtual char Delimiter { get; } /// public override T[]? 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 unconvertable inputs } } return typedValues.ToArray(); } return JsonSerializer.Deserialize(ref reader, options); } /// public override void Write(Utf8JsonWriter writer, T[]? value, JsonSerializerOptions options) { if (value is not null) { writer.WriteStartArray(); if (value.Length > 0) { var toWrite = value.Length - 1; foreach (var it in value) { var wrote = false; if (it is not null) { writer.WriteStringValue(it.ToString()); wrote = true; } if (toWrite > 0) { if (wrote) { writer.WriteStringValue(Delimiter.ToString()); } toWrite--; } } } writer.WriteEndArray(); } else { writer.WriteNullValue(); } } } }