Skip to content

Commit 17ba725

Browse files
committed
Add STJ converters
1 parent de3b92c commit 17ba725

10 files changed

Lines changed: 671 additions & 0 deletions
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Text.Json;
7+
using System.Text.Json.Serialization;
8+
9+
namespace NuGet.Protocol.Converters
10+
{
11+
/// <summary>
12+
/// Reads a JSON string or array of strings into a single comma-separated string.
13+
/// Equivalent to <see cref="MetadataFieldConverter"/> for System.Text.Json.
14+
/// </summary>
15+
/// <remarks>NSJ equivalent: <see cref="MetadataFieldConverter"/>.</remarks>
16+
internal sealed class MetadataFieldStjConverter : JsonConverter<string>
17+
{
18+
public override bool HandleNull => true;
19+
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
20+
{
21+
if (reader.TokenType == JsonTokenType.Null)
22+
{
23+
return string.Empty;
24+
}
25+
26+
if (reader.TokenType == JsonTokenType.StartArray)
27+
{
28+
var values = new List<string>();
29+
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
30+
{
31+
var s = reader.GetString();
32+
if (!string.IsNullOrWhiteSpace(s))
33+
{
34+
values.Add(s!);
35+
}
36+
}
37+
return string.Join(", ", values);
38+
}
39+
40+
return reader.GetString() ?? string.Empty;
41+
}
42+
43+
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
44+
=> throw new NotSupportedException();
45+
}
46+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Text.Json;
7+
using System.Text.Json.Serialization;
8+
9+
namespace NuGet.Protocol.Converters
10+
{
11+
/// <summary>
12+
/// Reads a JSON string or array of strings into an <see cref="IReadOnlyList{T}"/> of strings.
13+
/// Equivalent to <see cref="MetadataStringOrArrayConverter"/> for System.Text.Json.
14+
/// </summary>
15+
/// <remarks>NSJ equivalent: <see cref="MetadataStringOrArrayConverter"/>.</remarks>
16+
internal sealed class MetadataStringOrArrayStjConverter : JsonConverter<IReadOnlyList<string>>
17+
{
18+
public override IReadOnlyList<string>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
19+
{
20+
if (reader.TokenType == JsonTokenType.Null)
21+
{
22+
return null;
23+
}
24+
25+
if (reader.TokenType == JsonTokenType.String)
26+
{
27+
var str = reader.GetString();
28+
return string.IsNullOrWhiteSpace(str) ? null : new[] { str! };
29+
}
30+
31+
var values = new List<string>();
32+
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
33+
{
34+
values.Add(reader.GetString() ?? string.Empty);
35+
}
36+
return values.ToArray();
37+
}
38+
39+
public override void Write(Utf8JsonWriter writer, IReadOnlyList<string> value, JsonSerializerOptions options)
40+
=> throw new NotSupportedException();
41+
}
42+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Text.Json;
6+
using System.Text.Json.Serialization;
7+
using NuGet.Frameworks;
8+
9+
namespace NuGet.Protocol.Converters
10+
{
11+
/// <remarks>NSJ equivalent: <see cref="NuGetFrameworkConverter"/> (registered globally in <see cref="JsonExtensions.ObjectSerializationSettings"/>).</remarks>
12+
internal sealed class NuGetFrameworkStjConverter : JsonConverter<NuGetFramework>
13+
{
14+
public override bool HandleNull => true;
15+
public override NuGetFramework Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
16+
{
17+
if (reader.TokenType == JsonTokenType.Null)
18+
{
19+
return NuGetFramework.AnyFramework;
20+
}
21+
22+
var value = reader.GetString();
23+
return string.IsNullOrEmpty(value) ? NuGetFramework.AnyFramework : NuGetFramework.Parse(value!);
24+
}
25+
26+
public override void Write(Utf8JsonWriter writer, NuGetFramework value, JsonSerializerOptions options)
27+
=> writer.WriteStringValue(value.GetShortFolderName());
28+
}
29+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Text.Json;
6+
using System.Text.Json.Serialization;
7+
using NuGet.Versioning;
8+
9+
namespace NuGet.Protocol.Converters
10+
{
11+
/// <remarks>NSJ equivalent: <see cref="NuGetVersionConverter"/> (registered globally in <see cref="JsonExtensions.ObjectSerializationSettings"/>).</remarks>
12+
internal sealed class NuGetVersionStjConverter : JsonConverter<NuGetVersion>
13+
{
14+
public override NuGetVersion? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
15+
{
16+
if (reader.TokenType == JsonTokenType.Null)
17+
{
18+
return null;
19+
}
20+
21+
var str = reader.GetString();
22+
return str is null ? null : NuGetVersion.Parse(str);
23+
}
24+
25+
public override void Write(Utf8JsonWriter writer, NuGetVersion value, JsonSerializerOptions options)
26+
{
27+
if (value is null)
28+
{
29+
writer.WriteNullValue();
30+
}
31+
else
32+
{
33+
writer.WriteStringValue(value.ToString());
34+
}
35+
}
36+
}
37+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Text.Json;
7+
using System.Text.Json.Serialization;
8+
using NuGet.Frameworks;
9+
using NuGet.Packaging;
10+
using NuGet.Packaging.Core;
11+
12+
namespace NuGet.Protocol.Converters
13+
{
14+
/// <remarks>
15+
/// No explicit NSJ equivalent — NSJ relies on <c>[JsonConstructor]</c> and <c>[JsonProperty]</c> attributes
16+
/// on <see cref="PackageDependencyGroup"/> in NuGet.Packaging. STJ ignores those attributes, requiring this converter.
17+
/// </remarks>
18+
internal sealed class PackageDependencyGroupStjConverter : JsonConverter<PackageDependencyGroup>
19+
{
20+
private static readonly PackageDependencyStjConverter _dependencyConverter = new();
21+
22+
public override PackageDependencyGroup Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
23+
{
24+
if (reader.TokenType != JsonTokenType.StartObject)
25+
{
26+
throw new JsonException();
27+
}
28+
29+
NuGetFramework? targetFramework = null;
30+
var packages = new List<PackageDependency>();
31+
32+
while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
33+
{
34+
if (reader.TokenType != JsonTokenType.PropertyName)
35+
{
36+
continue;
37+
}
38+
39+
var propName = reader.GetString();
40+
reader.Read();
41+
42+
if (string.Equals(propName, JsonProperties.TargetFramework, StringComparison.OrdinalIgnoreCase))
43+
{
44+
if (reader.TokenType != JsonTokenType.Null)
45+
{
46+
var fw = reader.GetString();
47+
targetFramework = string.IsNullOrEmpty(fw) ? null : NuGetFramework.Parse(fw!);
48+
}
49+
}
50+
else if (string.Equals(propName, JsonProperties.Dependencies, StringComparison.OrdinalIgnoreCase))
51+
{
52+
if (reader.TokenType == JsonTokenType.StartArray)
53+
{
54+
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
55+
{
56+
packages.Add(_dependencyConverter.Read(ref reader, typeof(PackageDependency), options));
57+
}
58+
}
59+
else
60+
{
61+
reader.Skip();
62+
}
63+
}
64+
else
65+
{
66+
reader.Skip();
67+
}
68+
}
69+
70+
return new PackageDependencyGroup(targetFramework ?? NuGetFramework.AnyFramework, packages);
71+
}
72+
73+
public override void Write(Utf8JsonWriter writer, PackageDependencyGroup value, JsonSerializerOptions options)
74+
{
75+
writer.WriteStartObject();
76+
writer.WriteString(JsonProperties.TargetFramework, value.TargetFramework.GetShortFolderName());
77+
writer.WriteStartArray(JsonProperties.Dependencies);
78+
foreach (var pkg in value.Packages)
79+
{
80+
_dependencyConverter.Write(writer, pkg, options);
81+
}
82+
writer.WriteEndArray();
83+
writer.WriteEndObject();
84+
}
85+
}
86+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Text.Json;
6+
using System.Text.Json.Serialization;
7+
using NuGet.Packaging.Core;
8+
using NuGet.Versioning;
9+
10+
namespace NuGet.Protocol.Converters
11+
{
12+
/// <remarks>
13+
/// No explicit NSJ equivalent — NSJ relies on <c>[JsonConstructor]</c> and <c>[JsonProperty]</c> attributes
14+
/// on <see cref="PackageDependency"/> in NuGet.Packaging. STJ ignores those attributes, requiring this converter.
15+
/// </remarks>
16+
internal sealed class PackageDependencyStjConverter : JsonConverter<PackageDependency>
17+
{
18+
private static readonly VersionRangeStjConverter _versionRangeConverter = new();
19+
20+
public override PackageDependency Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
21+
{
22+
if (reader.TokenType != JsonTokenType.StartObject)
23+
{
24+
throw new JsonException();
25+
}
26+
27+
string? id = null;
28+
VersionRange? range = null;
29+
30+
while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
31+
{
32+
if (reader.TokenType != JsonTokenType.PropertyName)
33+
{
34+
continue;
35+
}
36+
37+
var propName = reader.GetString();
38+
reader.Read();
39+
40+
if (string.Equals(propName, JsonProperties.PackageId, StringComparison.OrdinalIgnoreCase))
41+
{
42+
id = reader.GetString();
43+
}
44+
else if (string.Equals(propName, JsonProperties.Range, StringComparison.OrdinalIgnoreCase))
45+
{
46+
if (reader.TokenType != JsonTokenType.Null)
47+
{
48+
range = _versionRangeConverter.Read(ref reader, typeof(VersionRange), options);
49+
}
50+
}
51+
else
52+
{
53+
reader.Skip();
54+
}
55+
}
56+
57+
return new PackageDependency(id!, range);
58+
}
59+
60+
public override void Write(Utf8JsonWriter writer, PackageDependency value, JsonSerializerOptions options)
61+
{
62+
writer.WriteStartObject();
63+
writer.WriteString(JsonProperties.PackageId, value.Id);
64+
writer.WritePropertyName(JsonProperties.Range);
65+
_versionRangeConverter.Write(writer, value.VersionRange, options);
66+
writer.WriteEndObject();
67+
}
68+
}
69+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Text.Json;
6+
using System.Text.Json.Serialization;
7+
8+
namespace NuGet.Protocol.Converters
9+
{
10+
/// <remarks>NSJ equivalent: <see cref="SafeBoolConverter"/>.</remarks>
11+
internal sealed class SafeBoolStjConverter : JsonConverter<bool>
12+
{
13+
public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
14+
{
15+
switch (reader.TokenType)
16+
{
17+
case JsonTokenType.True:
18+
return true;
19+
case JsonTokenType.False:
20+
case JsonTokenType.Null:
21+
return false;
22+
case JsonTokenType.String:
23+
return bool.TryParse(reader.GetString()?.Trim(), out bool flag) && flag;
24+
case JsonTokenType.Number:
25+
return reader.TryGetInt64(out long l) && l == 1;
26+
default:
27+
reader.Skip();
28+
return false;
29+
}
30+
}
31+
32+
public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOptions options)
33+
{
34+
throw new NotSupportedException();
35+
}
36+
}
37+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Text.Json;
6+
using System.Text.Json.Serialization;
7+
8+
namespace NuGet.Protocol.Converters
9+
{
10+
/// <remarks>NSJ equivalent: <see cref="SafeUriConverter"/>.</remarks>
11+
internal sealed class SafeUriStjConverter : JsonConverter<Uri>
12+
{
13+
public override Uri? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
14+
{
15+
if (reader.TokenType == JsonTokenType.Null)
16+
{
17+
return null;
18+
}
19+
20+
if (reader.TokenType == JsonTokenType.String)
21+
{
22+
Uri.TryCreate(reader.GetString()?.Trim(), UriKind.Absolute, out Uri? uri);
23+
return uri;
24+
}
25+
26+
reader.Skip();
27+
return null;
28+
}
29+
30+
public override void Write(Utf8JsonWriter writer, Uri value, JsonSerializerOptions options)
31+
{
32+
throw new NotSupportedException();
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)