Abstract JsonDelimitedArrayConverter

This commit is contained in:
Bond_009 2021-05-06 23:16:52 +02:00
parent 91c2a57b28
commit 4b9a64c18c
3 changed files with 87 additions and 121 deletions

View File

@ -9,73 +9,16 @@ namespace MediaBrowser.Common.Json.Converters
/// Convert comma delimited string to array of type. /// Convert comma delimited string to array of type.
/// </summary> /// </summary>
/// <typeparam name="T">Type to convert to.</typeparam> /// <typeparam name="T">Type to convert to.</typeparam>
public class JsonCommaDelimitedArrayConverter<T> : JsonConverter<T[]?> public sealed class JsonCommaDelimitedArrayConverter<T> : JsonDelimitedArrayConverter<T>
{ {
private readonly TypeConverter _typeConverter;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="JsonCommaDelimitedArrayConverter{T}"/> class. /// Initializes a new instance of the <see cref="JsonCommaDelimitedArrayConverter{T}"/> class.
/// </summary> /// </summary>
public JsonCommaDelimitedArrayConverter() public JsonCommaDelimitedArrayConverter() : base()
{ {
_typeConverter = TypeDescriptor.GetConverter(typeof(T));
} }
/// <inheritdoc /> /// <inheritdoc />
public override T[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) protected override char Delimiter => ',';
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}
if (reader.TokenType == JsonTokenType.String)
{
// GetString can't return null here because we already handled it above
var stringEntries = reader.GetString()!.Split(',', StringSplitOptions.RemoveEmptyEntries);
if (stringEntries.Length == 0)
{
return Array.Empty<T>();
}
var parsedValues = new object[stringEntries.Length];
var convertedCount = 0;
for (var i = 0; i < stringEntries.Length; i++)
{
try
{
parsedValues[i] = _typeConverter.ConvertFrom(stringEntries[i].Trim());
convertedCount++;
}
catch (FormatException)
{
// TODO log when upgraded to .Net6
// https://github.com/dotnet/runtime/issues/42975
// _logger.LogDebug(e, "Error converting value.");
}
}
var typedValues = new T[convertedCount];
var typedValueIndex = 0;
for (var i = 0; i < stringEntries.Length; i++)
{
if (parsedValues[i] != null)
{
typedValues.SetValue(parsedValues[i], typedValueIndex);
typedValueIndex++;
}
}
return typedValues;
}
return JsonSerializer.Deserialize<T[]>(ref reader, options);
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, T[]? value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
} }
} }

View File

@ -0,0 +1,81 @@
using System;
using System.ComponentModel;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace MediaBrowser.Common.Json.Converters
{
/// <summary>
/// Convert delimited string to array of type.
/// </summary>
/// <typeparam name="T">Type to convert to.</typeparam>
public abstract class JsonDelimitedArrayConverter<T> : JsonConverter<T[]?>
{
private readonly TypeConverter _typeConverter;
/// <summary>
/// Initializes a new instance of the <see cref="JsonDelimitedArrayConverter{T}"/> class.
/// </summary>
protected JsonDelimitedArrayConverter()
{
_typeConverter = TypeDescriptor.GetConverter(typeof(T));
}
/// <summary>
/// Gets the array delimiter.
/// </summary>
protected virtual char Delimiter { get; }
/// <inheritdoc />
public override T[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
{
// GetString can't return null here because we already handled it above
var stringEntries = reader.GetString()?.Split(Delimiter, StringSplitOptions.RemoveEmptyEntries);
if (stringEntries == null || stringEntries.Length == 0)
{
return Array.Empty<T>();
}
var parsedValues = new object[stringEntries.Length];
var convertedCount = 0;
for (var i = 0; i < stringEntries.Length; i++)
{
try
{
parsedValues[i] = _typeConverter.ConvertFrom(stringEntries[i].Trim());
convertedCount++;
}
catch (FormatException)
{
// TODO log when upgraded to .Net6
// https://github.com/dotnet/runtime/issues/42975
// _logger.LogDebug(e, "Error converting value.");
}
}
var typedValues = new T[convertedCount];
var typedValueIndex = 0;
for (var i = 0; i < stringEntries.Length; i++)
{
if (parsedValues[i] != null)
{
typedValues.SetValue(parsedValues[i], typedValueIndex);
typedValueIndex++;
}
}
return typedValues;
}
return JsonSerializer.Deserialize<T[]>(ref reader, options);
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, T[]? value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}
}

View File

@ -9,74 +9,16 @@ namespace MediaBrowser.Common.Json.Converters
/// Convert Pipe delimited string to array of type. /// Convert Pipe delimited string to array of type.
/// </summary> /// </summary>
/// <typeparam name="T">Type to convert to.</typeparam> /// <typeparam name="T">Type to convert to.</typeparam>
public class JsonPipeDelimitedArrayConverter<T> : JsonConverter<T[]> public sealed class JsonPipeDelimitedArrayConverter<T> : JsonDelimitedArrayConverter<T>
{ {
private readonly TypeConverter _typeConverter;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="JsonPipeDelimitedArrayConverter{T}"/> class. /// Initializes a new instance of the <see cref="JsonPipeDelimitedArrayConverter{T}"/> class.
/// </summary> /// </summary>
public JsonPipeDelimitedArrayConverter() public JsonPipeDelimitedArrayConverter() : base()
{ {
_typeConverter = TypeDescriptor.GetConverter(typeof(T));
} }
/// <inheritdoc /> /// <inheritdoc />
public override T[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) protected override char Delimiter => '|';
{
if (reader.TokenType == JsonTokenType.Null)
{
return Array.Empty<T>();
}
if (reader.TokenType == JsonTokenType.String)
{
// GetString can't return null here because we already handled it above
var stringEntries = reader.GetString()!.Split('|', StringSplitOptions.RemoveEmptyEntries);
if (stringEntries.Length == 0)
{
return Array.Empty<T>();
}
var parsedValues = new object[stringEntries.Length];
var convertedCount = 0;
for (var i = 0; i < stringEntries.Length; i++)
{
try
{
parsedValues[i] = _typeConverter.ConvertFrom(stringEntries[i].Trim());
convertedCount++;
}
catch (FormatException)
{
// TODO log when upgraded to .Net6
// https://github.com/dotnet/runtime/issues/42975
// _logger.LogDebug(e, "Error converting value.");
}
}
var typedValues = new T[convertedCount];
var typedValueIndex = 0;
for (var i = 0; i < stringEntries.Length; i++)
{
if (parsedValues[i] != null)
{
typedValues.SetValue(parsedValues[i], typedValueIndex);
typedValueIndex++;
}
}
return typedValues;
}
// can't return null here because we already handled it above
return JsonSerializer.Deserialize<T[]>(ref reader, options)!;
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, T[] value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
} }
} }