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