< Summary

Information
Class: Chronicler.StateJsonConverter<T1, T2>
Assembly: Chronicler
File(s): /home/runner/work/Chronicler/Chronicler/src/Chronicler/Serialization/Json/StateJsonConverter.cs
Line coverage
100%
Covered lines: 35
Uncovered lines: 0
Coverable lines: 35
Total lines: 89
Line coverage: 100%
Branch coverage
100%
Covered branches: 20
Total branches: 20
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%22100%
Read(...)100%11100%
EnsureStartObject(...)100%22100%
ReadStateProperty(...)100%66100%
ReadStateValue(...)100%44100%
EnsureEndObject(...)100%44100%
Write(...)100%22100%

File(s)

/home/runner/work/Chronicler/Chronicler/src/Chronicler/Serialization/Json/StateJsonConverter.cs

#LineLine coverage
 1using System;
 2using System.Text.Json;
 3using System.Text.Json.Serialization;
 4
 5namespace Chronicler;
 6
 7/// <summary>
 8/// Serializes and deserializes an object through its canonical state value.
 9/// </summary>
 10/// <typeparam name="TRecord">The state-backed record type.</typeparam>
 11/// <typeparam name="TState">The serializable state type.</typeparam>
 12public sealed class StateJsonConverter<TRecord, TState> : JsonConverter<TRecord>
 13    where TRecord : class, IStateBacked<TState>
 14{
 15    private const string StatePropertyName = "State";
 16
 17    private readonly Func<TState, TRecord> _factory;
 18
 19    /// <summary>
 20    /// Creates a converter that restores records from serialized state using the supplied factory.
 21    /// </summary>
 1122    public StateJsonConverter(Func<TState, TRecord> factory)
 23    {
 1124        _factory = factory ?? throw new ArgumentNullException(nameof(factory));
 1025    }
 26
 27    /// <inheritdoc />
 28    public override TRecord Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
 29    {
 930        EnsureStartObject(reader.TokenType, typeToConvert);
 831        ReadStateProperty(ref reader, typeToConvert);
 532        TState state = ReadStateValue(ref reader, typeToConvert, options);
 333        EnsureEndObject(ref reader, typeToConvert);
 34
 135        return _factory(state);
 36    }
 37
 38    private static void EnsureStartObject(JsonTokenType tokenType, Type typeToConvert)
 39    {
 940        if (tokenType != JsonTokenType.StartObject)
 141            throw new JsonException($"Expected JSON object for state-backed type '{typeToConvert}'.");
 842    }
 43
 44    private static void ReadStateProperty(ref Utf8JsonReader reader, Type typeToConvert)
 45    {
 846        if (!reader.Read())
 147            throw new JsonException($"Expected '{StatePropertyName}' property for state-backed type '{typeToConvert}'.")
 748        if (reader.TokenType != JsonTokenType.PropertyName || !reader.ValueTextEquals(StatePropertyName))
 249            throw new JsonException($"Expected '{StatePropertyName}' property for state-backed type '{typeToConvert}'.")
 550    }
 51
 52    private static TState ReadStateValue(
 53        ref Utf8JsonReader reader,
 54        Type typeToConvert,
 55        JsonSerializerOptions options)
 56    {
 557        if (!reader.Read())
 158            throw new JsonException($"Expected '{StatePropertyName}' value for state-backed type '{typeToConvert}'.");
 59
 460        TState? state = JsonSerializer.Deserialize<TState>(ref reader, options);
 461        if (state == null)
 162            throw new JsonException($"Unable to deserialize '{StatePropertyName}' for state-backed type '{typeToConvert}
 63
 364        return state;
 65    }
 66
 67    private static void EnsureEndObject(ref Utf8JsonReader reader, Type typeToConvert)
 68    {
 369        if (!reader.Read())
 170            throw new JsonException($"Expected end of JSON object for state-backed type '{typeToConvert}'.");
 271        if (reader.TokenType != JsonTokenType.EndObject)
 172            throw new JsonException($"Expected end of JSON object for state-backed type '{typeToConvert}'.");
 173    }
 74
 75    /// <inheritdoc />
 76    public override void Write(Utf8JsonWriter writer, TRecord value, JsonSerializerOptions options)
 77    {
 278        if (value == null)
 79        {
 180            writer.WriteNullValue();
 181            return;
 82        }
 83
 184        writer.WriteStartObject();
 185        writer.WritePropertyName(StatePropertyName);
 186        JsonSerializer.Serialize(writer, value.State, options);
 187        writer.WriteEndObject();
 188    }
 89}