< Summary

Information
Class: RaidLoop.Core.Contracts.FlexibleDateTimeOffsetJsonConverter
Assembly: RaidLoop.Core
File(s): /home/runner/work/RaidLoop/RaidLoop/src/RaidLoop.Core/Contracts/FlexibleDateTimeOffsetJsonConverter.cs
Line coverage
87%
Covered lines: 21
Uncovered lines: 3
Coverable lines: 24
Total lines: 96
Line coverage: 87.5%
Branch coverage
62%
Covered branches: 5
Total branches: 8
Branch coverage: 62.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
Read(...)50%8662.5%
Write(...)100%11100%
TryParseFlexible(...)100%22100%

File(s)

/home/runner/work/RaidLoop/RaidLoop/src/RaidLoop.Core/Contracts/FlexibleDateTimeOffsetJsonConverter.cs

#LineLine coverage
 1using System.Globalization;
 2using System.Text.Json;
 3using System.Text.Json.Serialization;
 4
 5namespace RaidLoop.Core.Contracts;
 6
 7public sealed class FlexibleDateTimeOffsetJsonConverter : JsonConverter<DateTimeOffset>
 8{
 19    internal static readonly string[] LegacyUtcFormats =
 110    [
 111        "yyyy-MM-dd HH:mm:ss.FFFFFF",
 112        "yyyy-MM-dd HH:mm:ss.FFFFFFF",
 113        "yyyy-MM-dd HH:mm:ss"
 114    ];
 15
 16    public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
 17    {
 918        if (reader.TokenType != JsonTokenType.String)
 19        {
 020            throw new JsonException($"Expected string token when parsing {nameof(DateTimeOffset)}.");
 21        }
 22
 923        var value = reader.GetString();
 924        if (string.IsNullOrWhiteSpace(value))
 25        {
 026            throw new JsonException("Timestamp string was null or empty.");
 27        }
 28
 929        if (TryParseFlexible(value, out var parsed))
 30        {
 931            return parsed;
 32        }
 33
 034        throw new JsonException($"Unable to parse DateTimeOffset value '{value}'.");
 35    }
 36
 37    public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
 38    {
 539        writer.WriteStringValue(value.ToUniversalTime().ToString("O", CultureInfo.InvariantCulture));
 540    }
 41
 42    internal static bool TryParseFlexible(string value, out DateTimeOffset parsed)
 43    {
 1044        if (DateTimeOffset.TryParseExact(
 1045                value,
 1046                LegacyUtcFormats,
 1047                CultureInfo.InvariantCulture,
 1048                DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal,
 1049                out parsed))
 50        {
 151            return true;
 52        }
 53
 954        return DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out parsed);
 55    }
 56}
 57
 58public sealed class FlexibleNullableDateTimeOffsetJsonConverter : JsonConverter<DateTimeOffset?>
 59{
 60    public override DateTimeOffset? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
 61    {
 62        if (reader.TokenType == JsonTokenType.Null)
 63        {
 64            return null;
 65        }
 66
 67        if (reader.TokenType != JsonTokenType.String)
 68        {
 69            throw new JsonException($"Expected string token when parsing {nameof(DateTimeOffset)}.");
 70        }
 71
 72        var value = reader.GetString();
 73        if (string.IsNullOrWhiteSpace(value))
 74        {
 75            return null;
 76        }
 77
 78        if (FlexibleDateTimeOffsetJsonConverter.TryParseFlexible(value, out var parsed))
 79        {
 80            return parsed;
 81        }
 82
 83        throw new JsonException($"Unable to parse DateTimeOffset value '{value}'.");
 84    }
 85
 86    public override void Write(Utf8JsonWriter writer, DateTimeOffset? value, JsonSerializerOptions options)
 87    {
 88        if (value is null)
 89        {
 90            writer.WriteNullValue();
 91            return;
 92        }
 93
 94        writer.WriteStringValue(value.Value.ToUniversalTime().ToString("O", CultureInfo.InvariantCulture));
 95    }
 96}