Skip to content

Commit

Permalink
STJ: remove custom DateOnly/TimeOnly converters
Browse files Browse the repository at this point in the history
Not needed anymore, the types are natively supported by the serialized
  • Loading branch information
exyi committed Apr 26, 2024
1 parent 8c4bcbf commit dcba751
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public static StaticCommandInvocationPlan DeserializePlan(ref Utf8JsonReader jso
method = method.MakeGenericMethod(generics);
}

var methodParameters = method.GetParameters();
ParameterInfo?[] methodParameters = method.GetParameters();
if (!method.IsStatic)
{
methodParameters = [ null, ..methodParameters ];
Expand All @@ -153,11 +153,11 @@ public static StaticCommandInvocationPlan DeserializePlan(ref Utf8JsonReader jso
args[i] = type switch
{
StaticCommandParameterType.Argument or StaticCommandParameterType.Inject =>
new StaticCommandParameterPlan(type, json.TokenType == JsonTokenType.Null ? paramType : Type.GetType(json.GetString())),
new StaticCommandParameterPlan(type, json.TokenType == JsonTokenType.Null ? paramType : Type.GetType(json.GetString()!)),
StaticCommandParameterType.Constant =>
new StaticCommandParameterPlan(type, JsonSerializer.Deserialize(ref json, paramType)),
StaticCommandParameterType.DefaultValue =>
new StaticCommandParameterPlan(type, methodParameters[i].DefaultValue),
new StaticCommandParameterPlan(type, methodParameters[i]!.DefaultValue),
StaticCommandParameterType.Invocation =>
new StaticCommandParameterPlan(type, DeserializePlan(ref json)),
_ => throw new NotSupportedException(type.ToString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ private JsonSerializerOptions CreateSettings()
{
Converters = {
new DotvvmDateTimeConverter(),
new DotvvmDateOnlyConverter(),
new DotvvmTimeOnlyConverter(),
new DotvvmObjectConverter(),
new DotvvmEnumConverter(),
new DotvvmDictionaryConverter(),
Expand Down
22 changes: 18 additions & 4 deletions src/Framework/Framework/Utils/SystemTextJsonUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json;

namespace DotVVM.Framework.Utils
Expand Down Expand Up @@ -76,12 +77,19 @@ public static IEnumerable<string> EnumerateStringArray(this JsonElement json)
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AssertToken(this in Utf8JsonReader reader, JsonTokenType type)
{
if (reader.TokenType != type)
{
throw new JsonException($"Expected token of type {type}, but got {reader.TokenType}.");
}
ThrowUnexpectedToken(in reader, type);
}

static void ThrowUnexpectedToken(in Utf8JsonReader reader, JsonTokenType expected)
{
var value = reader.TokenType is JsonTokenType.String or JsonTokenType.PropertyName or JsonTokenType.Number
? $" (\"{StringUtils.Utf8Decode(reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan.ToArray())}\")"
: "";
throw new JsonException($"Expected token of type {expected}, but got {reader.TokenType}{value} at position {reader.BytesConsumed}.");
}

public static void AssertRead(this ref Utf8JsonReader reader, JsonTokenType type)
Expand All @@ -90,10 +98,16 @@ public static void AssertRead(this ref Utf8JsonReader reader, JsonTokenType type
AssertRead(ref reader);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AssertRead(this ref Utf8JsonReader reader)
{
if (!reader.Read())
throw new JsonException($"Expected end of stream.");
ThrowUnexpectedEndOfStream(in reader);
}

public static void ThrowUnexpectedEndOfStream(in Utf8JsonReader reader)
{
throw new JsonException($"Unexpected end of stream at position {reader.BytesConsumed}.");
}

public static string? ReadString(this ref Utf8JsonReader reader)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class DotvvmByteArrayConverter : JsonConverter<byte[]>
switch (reader.TokenType)
{
case JsonTokenType.Number:
list.Add((byte)reader.GetUInt16());
list.Add(checked((byte)reader.GetUInt16()));
break;
case JsonTokenType.EndArray:
return list.ToArray();
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -46,44 +46,40 @@ public override void Write(Utf8JsonWriter json, TDictionary value, JsonSerialize
}
public override TDictionary? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartArray)
throw new JsonException($"Expected StartArray, but got {reader.TokenType}.");
reader.Read();
reader.AssertRead(JsonTokenType.StartArray);
var dict = new Dictionary<K, V>();
while (reader.TokenType != JsonTokenType.EndArray)
{
if (reader.TokenType != JsonTokenType.StartObject)
throw new JsonException($"Expected StartObject, but got {reader.TokenType}.");
reader.Read();
reader.AssertRead(JsonTokenType.StartObject);
(K key, V value) item = default;
bool hasKey = false, hasValue = false;
while (reader.TokenType != JsonTokenType.EndObject)
{
if (reader.TokenType != JsonTokenType.PropertyName)
throw new JsonException($"Expected PropertyName, but got {reader.TokenType}.");
reader.AssertToken(JsonTokenType.PropertyName);

if (reader.ValueTextEquals("Key"u8))
{
reader.Read();
reader.AssertRead();
item.key = SystemTextJsonUtils.Deserialize<K>(ref reader, options)!;
reader.Read();
hasKey = true;
}
else if (reader.ValueTextEquals("Value"u8))
{
reader.Read();
reader.AssertRead();
item.value = SystemTextJsonUtils.Deserialize<V>(ref reader, options)!;
reader.Read();
hasValue = true;
}
else
{
reader.Read();
reader.AssertRead();
reader.Skip();
reader.Read();
}
reader.AssertRead();
}
if (!hasKey || !hasValue) throw new JsonException("Missing Key or Value property in dictionary item.");
dict.Add(item.key!, item.value);
reader.Read();
reader.AssertRead(JsonTokenType.EndObject);
}
reader.Read();

if (dict is TDictionary result)
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace DotVVM.Framework.ViewModel.Serialization
{
/// <summary> Mimicks Newtonsoft.Json behavior for System.Object - number -> double, string -> string, true/false -> bool, otherwise JsonElement </summary>
public class DotvvmObjectConverter : JsonConverter<object?>
{
public override void Write(Utf8JsonWriter writer, object? value, JsonSerializerOptions options)
Expand Down

This file was deleted.

20 changes: 19 additions & 1 deletion src/Tests/ViewModel/SerializerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -468,11 +468,29 @@ public void SupportsDateTime()
Assert.AreEqual(obj.TimeOnly, obj2.TimeOnly);

Assert.AreEqual("2000-01-01", json["DateOnly"].GetValue<string>());
Assert.AreEqual("15:00:00.0000000", json["TimeOnly"].GetValue<string>());
Assert.AreEqual("15:00:00", json["TimeOnly"].GetValue<string>());
Assert.AreEqual("2000-01-01T15:00:00", json["DateTime1"].GetValue<string>());
Assert.AreEqual("2000-01-01T15:00:00", json["DateTime2"].GetValue<string>());
Assert.AreEqual("2000-01-01T15:00:00", json["DateTime3"].GetValue<string>());
}

[TestMethod]
public void SupportsDateTime_MicrosecondPrecision()
{
var obj = new TestViewModelWithDateTimes() {
DateTime1 = new DateTime(2000, 1, 2, 15, 16, 17).AddMilliseconds(123.456),
TimeOnly = new TimeOnly(15, 16, 17).Add(TimeSpan.FromMilliseconds(123.456))
};
var (obj2, json) = SerializeAndDeserialize(obj);
Console.WriteLine(json);
Assert.AreEqual(obj.DateTime1, obj2.DateTime1);
Assert.AreEqual(DateTimeKind.Unspecified, obj2.DateTime1.Kind);
Assert.AreEqual(obj.TimeOnly, obj2.TimeOnly);
Assert.AreEqual(obj.TimeOnly.Ticks, obj2.TimeOnly.Ticks);

Assert.AreEqual("2000-01-02T15:16:17.123456", json["DateTime1"].GetValue<string>());
Assert.AreEqual("15:16:17.1234560", json["TimeOnly"].GetValue<string>());
}

[TestMethod]
public void SupportsEnums()
Expand Down

0 comments on commit dcba751

Please sign in to comment.