• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Aldaviva / Unfucked / 23378203323

21 Mar 2026 10:59AM UTC coverage: 35.442% (-11.7%) from 47.183%
23378203323

push

github

Aldaviva
Seal all possible classes for allegedly higher performance, since they weren't actually subclassable anyway due to C# not making methods virtual by default. If this change does more harm than good, blame Stephen Toub.

573 of 1629 branches covered (35.17%)

14 of 72 new or added lines in 15 files covered. (19.44%)

488 existing lines in 30 files now uncovered.

975 of 2751 relevant lines covered (35.44%)

162.06 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

42.5
/HTTP/Serialization/JsonBodyReader.cs
1
using System.Text;
2
using System.Text.Json;
3
using System.Text.Json.Nodes;
4
using System.Text.Json.Serialization;
5
using Unfucked.HTTP.Config;
6
#if NET6_0_OR_GREATER
7
using System.Net.Mime;
8
#endif
9

10
namespace Unfucked.HTTP.Serialization;
11

12
public sealed class JsonBodyReader: MessageBodyReader {
13

14
    private const string APPLICATION_JSON_MEDIA_TYPE =
15
#if NET6_0_OR_GREATER
16
        MediaTypeNames.Application.Json;
17
#else
18
        "application/json";
19
#endif
20

UNCOV
21
    internal static readonly JsonSerializerOptions DEFAULT_JSON_OPTIONS = new(JsonSerializerDefaults.Web) {
×
UNCOV
22
        ReadCommentHandling = JsonCommentHandling.Skip,
×
UNCOV
23
        Converters = {
×
UNCOV
24
            new JsonStringEnumConverter(new KernighanRitchieCEnumToLowerCamelCaseNamingPolicy())
×
UNCOV
25
        }
×
UNCOV
26
    };
×
27

28
    public bool CanRead<T>(string? mimeType, string? bodyPrefix) =>
UNCOV
29
        typeof(T) == typeof(JsonDocument) ||
×
UNCOV
30
        typeof(T) == typeof(JsonNode) ||
×
UNCOV
31
        typeof(T) == typeof(JsonObject) ||
×
UNCOV
32
        typeof(T) == typeof(JsonArray) ||
×
UNCOV
33
        typeof(T) == typeof(JsonValue) ||
×
UNCOV
34
        mimeType == APPLICATION_JSON_MEDIA_TYPE ||
×
UNCOV
35
        (mimeType?.EndsWith("+json") ?? false) ||
×
UNCOV
36
        (bodyPrefix != null && (
×
UNCOV
37
            bodyPrefix.StartsWith('{') ||
×
UNCOV
38
            bodyPrefix.StartsWith('[') ||
×
UNCOV
39
            bodyPrefix.Contains("\"$schema\"")));
×
40

41
    /*
42
     * Don't parse using the convenience extension methods from System.Net.Http.Json because that closes the response body stream even when an exception is thrown, so we can't read the body to create the exception.
43
     * Instead, rely on UnfuckedWebTarget.DisposeIfNotStream<T> to close the stream when the entire response processing is done.
44
     */
45
    /// <exception cref="JsonException"></exception>
46
    public async Task<T> Read<T>(HttpContent responseBody, Encoding? responseEncoding, Configurable? clientConfig, CancellationToken cancellationToken) {
UNCOV
47
        JsonSerializerOptions jsonOptions = (clientConfig?.Property(PropertyKey.JsonSerializerOptions, out JsonSerializerOptions? j) ?? false ? j : DEFAULT_JSON_OPTIONS)!;
×
48

UNCOV
49
        Task<Stream> readAsStreamAsync =
×
UNCOV
50
#if NET5_0_OR_GREATER
×
UNCOV
51
            responseBody.ReadAsStreamAsync(cancellationToken);
×
52
#else
53
            responseBody.ReadAsStreamAsync();
54
#endif
55

UNCOV
56
        return (await JsonSerializer.DeserializeAsync<T>(await readAsStreamAsync.ConfigureAwait(false), jsonOptions, cancellationToken).ConfigureAwait(false))!;
×
UNCOV
57
    }
×
58

59
}
60

61
internal sealed class KernighanRitchieCEnumToLowerCamelCaseNamingPolicy: JsonNamingPolicy {
62

63
    public override string ConvertName(string name) {
64
        if (!name.HasText()) return name;
2,826!
65

66
        bool isNewWord    = false;
2,826✔
67
        bool allUppercase = true;
2,826✔
68

69
        Span<char> output      = stackalloc char[name.Length];
2,826✔
70
        int        outputIndex = 0;
2,826✔
71
        for (int inputIndex = 0; inputIndex < name.Length; inputIndex++) {
80,516✔
72
            char c = name[inputIndex];
37,432✔
73

74
            if (c == '_' && inputIndex != 0 && name[inputIndex - 1] != '_') {
37,432✔
75
                isNewWord = true;
1,146✔
76
                continue;
1,146✔
77
            } else if (char.IsLower(c)) {
36,286✔
78
                allUppercase = false;
15,998✔
79
            } else if (!allUppercase || (inputIndex != 0 && inputIndex + 1 < name.Length && char.IsLower(name[inputIndex + 1]))) {
20,288✔
80
                isNewWord = true;
2,080✔
81
            }
82

83
            output[outputIndex++] = isNewWord ? char.ToUpperInvariant(c) : char.ToLowerInvariant(c);
36,286✔
84
            isNewWord             = char.IsNumber(c);
36,286✔
85
        }
86

87
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
88
        return new string(output[..outputIndex]);
2,826✔
89
#else
90
        return new string(output.Slice(0, outputIndex).ToArray());
91
#endif
92
    }
93

94
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc