Added or extended support for the following types that may appear in the "value" property in CF specifications payload: - Integer - Double - String - Boolean (true and false) - Null Fixes #318pull/319/head
parent
99c4e1ac35
commit
64cfa97e6f
@ -1,22 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace Recyclarr.TrashGuide.CustomFormat;
|
|
||||||
|
|
||||||
public class FieldValueConverter : JsonConverter<object>
|
|
||||||
{
|
|
||||||
public override object? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
||||||
{
|
|
||||||
return reader.TokenType switch
|
|
||||||
{
|
|
||||||
JsonTokenType.Number => reader.GetInt32(),
|
|
||||||
JsonTokenType.String => reader.GetString(),
|
|
||||||
_ => throw new JsonException($"CF field of type {reader.TokenType} is not supported")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
|
|
||||||
{
|
|
||||||
JsonSerializer.Serialize(writer, value, options);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,57 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace Recyclarr.TrashGuide.CustomFormat;
|
||||||
|
|
||||||
|
public class NondeterministicValueConverter : JsonConverter<object>
|
||||||
|
{
|
||||||
|
public override object? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
return reader.TokenType switch
|
||||||
|
{
|
||||||
|
JsonTokenType.Number when reader.TryGetInt32(out var value) => value,
|
||||||
|
JsonTokenType.Number when reader.TryGetDouble(out var value) => value,
|
||||||
|
JsonTokenType.String => reader.GetString(),
|
||||||
|
JsonTokenType.True => true,
|
||||||
|
JsonTokenType.False => false,
|
||||||
|
JsonTokenType.Null => null,
|
||||||
|
_ => throw new JsonException($"CF field of type {reader.TokenType} is not supported")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case null:
|
||||||
|
writer.WriteNullValue();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case string strValue:
|
||||||
|
writer.WriteStringValue(strValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case int intValue:
|
||||||
|
writer.WriteNumberValue(intValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case double doubleValue:
|
||||||
|
writer.WriteNumberValue(doubleValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case bool boolValue:
|
||||||
|
writer.WriteBooleanValue(boolValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new JsonException($"Serialization of type {value.GetType()} is not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new JsonException($"Serialization failed for value of type {value?.GetType()}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using Recyclarr.TrashGuide.CustomFormat;
|
||||||
|
|
||||||
|
namespace Recyclarr.Tests.TrashGuide.CustomFormat;
|
||||||
|
|
||||||
|
[Parallelizable(ParallelScope.All)]
|
||||||
|
public class NondeterministicValueConverterTest
|
||||||
|
{
|
||||||
|
private JsonSerializerOptions _options;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_options = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
Converters = {new NondeterministicValueConverter()},
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Deserialize_int_value()
|
||||||
|
{
|
||||||
|
const string json = "42";
|
||||||
|
var result = JsonSerializer.Deserialize<object>(json, _options);
|
||||||
|
result.Should().Be(42);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Deserialize_double_value()
|
||||||
|
{
|
||||||
|
const string json = "42.5";
|
||||||
|
var result = JsonSerializer.Deserialize<object>(json, _options);
|
||||||
|
result.Should().Be(42.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Deserialize_string_value()
|
||||||
|
{
|
||||||
|
const string json = "\"test string\"";
|
||||||
|
var result = JsonSerializer.Deserialize<object>(json, _options);
|
||||||
|
result.Should().Be("test string");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Deserialize_boolean_value_true()
|
||||||
|
{
|
||||||
|
const string json = "true";
|
||||||
|
var result = JsonSerializer.Deserialize<object>(json, _options);
|
||||||
|
result.Should().Be(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Deserialize_boolean_value_false()
|
||||||
|
{
|
||||||
|
const string json = "false";
|
||||||
|
var result = JsonSerializer.Deserialize<object>(json, _options);
|
||||||
|
result.Should().Be(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Deserialize_null_value()
|
||||||
|
{
|
||||||
|
const string json = "null";
|
||||||
|
var result = JsonSerializer.Deserialize<object>(json, _options);
|
||||||
|
result.Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Deserialize_unsupported_type_should_throw()
|
||||||
|
{
|
||||||
|
const string json = "{ }";
|
||||||
|
Action act = () => JsonSerializer.Deserialize<object>(json, _options);
|
||||||
|
act.Should().Throw<JsonException>()
|
||||||
|
.WithMessage("CF field of type StartObject is not supported*")
|
||||||
|
.And.InnerException.Should().BeNull();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue