< Summary - AsyncResponse (Release / net8.0+net10.0 / unit+integration)

Information
Class: AsyncResponse.RawJsonResponse
Assembly: AsyncResponse.Core
File(s): /home/runner/work/AsyncResponse/AsyncResponse/src/AsyncResponse.Core/RawJsonResponse.cs
Line coverage
100%
Covered lines: 32
Uncovered lines: 0
Coverable lines: 32
Total lines: 80
Line coverage: 100%
Branch coverage
100%
Covered branches: 12
Total branches: 12
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%11100%
get_Json()100%11100%
DeserializeUntyped()100%22100%
Deserialize<T>()100%11100%
Deserialize(...)100%1010100%

File(s)

/home/runner/work/AsyncResponse/AsyncResponse/src/AsyncResponse.Core/RawJsonResponse.cs

#LineLine coverage
 1namespace AsyncResponse;
 2
 3/// <summary>
 4/// Raw broker/webhook response payload that can be materialized into the active waiter's payload
 5/// type without first allocating an intermediate JsonElement.
 6/// </summary>
 7internal sealed class RawJsonResponse
 8{
 9    private readonly string _json;
 10
 11    // One instance is shared across every subscriber of a correlation id, and fan-out dispatch can
 12    // materialize payloads from multiple threads. All memoization state below is guarded by _gate:
 13    // an unsynchronized publication could hand one waiter a torn (type set, payload null) pair, and
 14    // a plain Dictionary corrupts under concurrent writes. The uncontended lock is cheap next to
 15    // the deserialization it guards, and allocation behavior is unchanged.
 316    private readonly object _gate = new();
 17    private Dictionary<Type, object?>? _typedPayloads;
 18    private Type? _singlePayloadType;
 19    private object? _singlePayload;
 20    private object? _untypedPayload;
 21    private bool _hasUntypedPayload;
 22
 23    /// <summary>Runs the RawJsonResponse operation.</summary>
 324    public RawJsonResponse(string json)
 25    {
 326        JsonSafety.ThrowIfClearlyNotJson(json);
 327        _json = json;
 328    }
 29
 330    public string Json => _json;
 31
 32    /// <summary>Runs the DeserializeUntyped operation.</summary>
 33    public object? DeserializeUntyped()
 34    {
 335        lock (_gate)
 36        {
 337            if (_hasUntypedPayload)
 338                return _untypedPayload;
 39
 240            _untypedPayload = JsonSafety.SafeDeserialize<object?>(_json);
 341            _hasUntypedPayload = true;
 342            return _untypedPayload;
 43        }
 344    }
 45
 46    /// <summary>Runs the Deserialize operation.</summary>
 347    public T? Deserialize<T>() => (T?)Deserialize(typeof(T));
 48
 49    /// <summary>Runs the Deserialize operation.</summary>
 50    public object? Deserialize(Type payloadType)
 51    {
 252        lock (_gate)
 53        {
 254            if (_singlePayloadType == payloadType)
 255                return _singlePayload;
 56
 257            if (_typedPayloads?.TryGetValue(payloadType, out var cached) == true)
 258                return cached;
 59
 260            var payload = JsonSafety.SafeDeserialize(_json, payloadType);
 261            if (_singlePayloadType is null)
 62            {
 263                _singlePayloadType = payloadType;
 264                _singlePayload = payload;
 265                return payload;
 66            }
 67
 268            if (_typedPayloads is null)
 69            {
 270                _typedPayloads = new Dictionary<Type, object?>
 271                {
 272                    [_singlePayloadType] = _singlePayload
 273                };
 74            }
 75
 276            _typedPayloads.Add(payloadType, payload);
 277            return payload;
 78        }
 279    }
 80}