You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
1.5 KiB
54 lines
1.5 KiB
9 months ago
|
using System.Text.Json;
|
||
|
using System.Text.Json.Serialization;
|
||
|
|
||
|
namespace Recyclarr.Json;
|
||
|
|
||
|
public class CollectionJsonConverter : JsonConverterFactory
|
||
|
{
|
||
|
public override bool CanConvert(Type typeToConvert)
|
||
|
{
|
||
|
return !IsExcludedType(typeToConvert) &&
|
||
|
typeToConvert.IsGenericType &&
|
||
|
IsAssignableToGenericType(typeToConvert, typeof(IEnumerable<>));
|
||
|
}
|
||
|
|
||
|
private static bool IsExcludedType(Type type)
|
||
|
{
|
||
|
return type.IsPrimitive ||
|
||
|
type == typeof(string);
|
||
|
}
|
||
|
|
||
|
private static bool IsAssignableToGenericType(Type givenType, Type genericType)
|
||
|
{
|
||
|
var interfaceTypes = givenType.GetInterfaces()
|
||
|
.Where(x => x.IsGenericType)
|
||
|
.Select(x => x.GetGenericTypeDefinition());
|
||
|
|
||
|
return interfaceTypes.Contains(genericType);
|
||
|
}
|
||
|
|
||
|
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
|
||
|
{
|
||
|
var elementType = typeToConvert.GetGenericArguments()[0];
|
||
|
Type converterType;
|
||
|
|
||
|
if (typeToConvert.GetGenericTypeDefinition() == typeof(IReadOnlyCollection<>))
|
||
|
{
|
||
|
converterType = typeof(ReadOnlyCollectionJsonConverter<>).MakeGenericType(elementType);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
throw new JsonException();
|
||
|
}
|
||
|
|
||
|
var instance = Activator.CreateInstance(converterType);
|
||
|
|
||
|
if (instance is null)
|
||
|
{
|
||
|
throw new JsonException();
|
||
|
}
|
||
|
|
||
|
return (JsonConverter) instance;
|
||
|
}
|
||
|
}
|