Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace NuGet.Protocol.Converters
{
/// <summary>
/// Reads a JSON string or array of strings into a single comma-separated string.
/// Equivalent to <see cref="MetadataFieldConverter"/> for System.Text.Json.
/// </summary>
/// <remarks>NSJ equivalent: <see cref="MetadataFieldConverter"/>.</remarks>
internal sealed class MetadataFieldStjConverter : JsonConverter<string>
{
public override bool HandleNull => true;
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return string.Empty;
}

if (reader.TokenType == JsonTokenType.StartArray)
{
var values = new List<string>();
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
{
var s = reader.GetString();
if (!string.IsNullOrWhiteSpace(s))
{
values.Add(s!);
}
}
return string.Join(", ", values);
}

return reader.GetString() ?? string.Empty;
}

public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
=> throw new NotSupportedException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace NuGet.Protocol.Converters
{
/// <summary>
/// Reads a JSON string or array of strings into an <see cref="IReadOnlyList{T}"/> of strings.
/// Equivalent to <see cref="MetadataStringOrArrayConverter"/> for System.Text.Json.
/// </summary>
/// <remarks>NSJ equivalent: <see cref="MetadataStringOrArrayConverter"/>.</remarks>
internal sealed class MetadataStringOrArrayStjConverter : JsonConverter<IReadOnlyList<string>>
{
public override IReadOnlyList<string>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}

if (reader.TokenType == JsonTokenType.String)
{
var str = reader.GetString();
return string.IsNullOrWhiteSpace(str) ? null : new[] { str! };
}

var values = new List<string>();
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
{
values.Add(reader.GetString() ?? string.Empty);
}
return values.ToArray();
}

public override void Write(Utf8JsonWriter writer, IReadOnlyList<string> value, JsonSerializerOptions options)
=> throw new NotSupportedException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using NuGet.Frameworks;

namespace NuGet.Protocol.Converters
{
/// <remarks>NSJ equivalent: <see cref="NuGetFrameworkConverter"/> (registered globally in <see cref="JsonExtensions.ObjectSerializationSettings"/>).</remarks>
internal sealed class NuGetFrameworkStjConverter : JsonConverter<NuGetFramework>
{
public override bool HandleNull => true;
public override NuGetFramework Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return NuGetFramework.AnyFramework;
}

var value = reader.GetString();
return string.IsNullOrEmpty(value) ? NuGetFramework.AnyFramework : NuGetFramework.Parse(value!);
}

public override void Write(Utf8JsonWriter writer, NuGetFramework value, JsonSerializerOptions options)
=> writer.WriteStringValue(value.GetShortFolderName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using NuGet.Versioning;

namespace NuGet.Protocol.Converters
{
/// <remarks>NSJ equivalent: <see cref="NuGetVersionConverter"/> (registered globally in <see cref="JsonExtensions.ObjectSerializationSettings"/>).</remarks>
internal sealed class NuGetVersionStjConverter : JsonConverter<NuGetVersion>
{
public override NuGetVersion? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}

var str = reader.GetString();
return str is null ? null : NuGetVersion.Parse(str);
}

public override void Write(Utf8JsonWriter writer, NuGetVersion value, JsonSerializerOptions options)
{
if (value is null)
{
writer.WriteNullValue();
}
else
{
writer.WriteStringValue(value.ToString());
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
using NuGet.Frameworks;
using NuGet.Packaging;
using NuGet.Packaging.Core;

namespace NuGet.Protocol.Converters
{
/// <remarks>
/// No explicit NSJ equivalent — NSJ relies on <c>[JsonConstructor]</c> and <c>[JsonProperty]</c> attributes
/// on <see cref="PackageDependencyGroup"/> in NuGet.Packaging. STJ ignores those attributes, requiring this converter.
/// </remarks>
internal sealed class PackageDependencyGroupStjConverter : JsonConverter<PackageDependencyGroup>
{
private static readonly PackageDependencyStjConverter _dependencyConverter = new();

public override PackageDependencyGroup Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException();
}

NuGetFramework? targetFramework = null;
var packages = new List<PackageDependency>();

while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
{
if (reader.TokenType != JsonTokenType.PropertyName)
{
continue;
}

var propName = reader.GetString();
reader.Read();

if (string.Equals(propName, JsonProperties.TargetFramework, StringComparison.OrdinalIgnoreCase))
{
if (reader.TokenType != JsonTokenType.Null)
{
var fw = reader.GetString();
targetFramework = string.IsNullOrEmpty(fw) ? null : NuGetFramework.Parse(fw!);
}
}
else if (string.Equals(propName, JsonProperties.Dependencies, StringComparison.OrdinalIgnoreCase))
{
if (reader.TokenType == JsonTokenType.StartArray)
{
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
{
packages.Add(_dependencyConverter.Read(ref reader, typeof(PackageDependency), options));
}
}
else
{
reader.Skip();
}
}
else
{
reader.Skip();
}
}

return new PackageDependencyGroup(targetFramework ?? NuGetFramework.AnyFramework, packages);
}

public override void Write(Utf8JsonWriter writer, PackageDependencyGroup value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteString(JsonProperties.TargetFramework, value.TargetFramework.GetShortFolderName());
writer.WriteStartArray(JsonProperties.Dependencies);
foreach (var pkg in value.Packages)
{
_dependencyConverter.Write(writer, pkg, options);
}
writer.WriteEndArray();
writer.WriteEndObject();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using NuGet.Packaging.Core;
using NuGet.Versioning;

namespace NuGet.Protocol.Converters
{
/// <remarks>
/// No explicit NSJ equivalent — NSJ relies on <c>[JsonConstructor]</c> and <c>[JsonProperty]</c> attributes
/// on <see cref="PackageDependency"/> in NuGet.Packaging. STJ ignores those attributes, requiring this converter.
/// </remarks>
internal sealed class PackageDependencyStjConverter : JsonConverter<PackageDependency>
{
private static readonly VersionRangeStjConverter _versionRangeConverter = new();

public override PackageDependency Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException();
}

string? id = null;
VersionRange? range = null;

while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
{
if (reader.TokenType != JsonTokenType.PropertyName)
{
continue;
}

var propName = reader.GetString();
reader.Read();

if (string.Equals(propName, JsonProperties.PackageId, StringComparison.OrdinalIgnoreCase))
{
id = reader.GetString();
}
else if (string.Equals(propName, JsonProperties.Range, StringComparison.OrdinalIgnoreCase))
{
if (reader.TokenType != JsonTokenType.Null)
{
range = _versionRangeConverter.Read(ref reader, typeof(VersionRange), options);
}
}
else
{
reader.Skip();
}
}

return new PackageDependency(id!, range);
}

public override void Write(Utf8JsonWriter writer, PackageDependency value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteString(JsonProperties.PackageId, value.Id);
writer.WritePropertyName(JsonProperties.Range);
_versionRangeConverter.Write(writer, value.VersionRange, options);
writer.WriteEndObject();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Text.Json.Serialization;
using NuGet.Protocol.Model;

namespace NuGet.Protocol.Converters
{
#pragma warning disable CS3016 // Arrays as attribute arguments is not CLS-compliant
[JsonSourceGenerationOptions(
PropertyNameCaseInsensitive = true,
GenerationMode = JsonSourceGenerationMode.Metadata,
Converters = new[]
{
typeof(NuGetVersionStjConverter),
typeof(VersionInfoStjConverter),
typeof(PackageDependencyGroupStjConverter),
typeof(PackageDependencyStjConverter),
typeof(VersionRangeStjConverter)
})]
#pragma warning restore CS3016 // Arrays as attribute arguments is not CLS-compliant
[JsonSerializable(typeof(RegistrationIndex))]
[JsonSerializable(typeof(RegistrationPage))]
internal partial class PackageMetadataJsonContext : JsonSerializerContext
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace NuGet.Protocol.Converters
{
/// <remarks>NSJ equivalent: <see cref="SafeBoolConverter"/>.</remarks>
internal sealed class SafeBoolStjConverter : JsonConverter<bool>
{
public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.True:
return true;
case JsonTokenType.False:
case JsonTokenType.Null:
return false;
case JsonTokenType.String:
return bool.TryParse(reader.GetString()?.Trim(), out bool flag) && flag;
case JsonTokenType.Number:
return reader.TryGetInt64(out long l) && l == 1;
default:
reader.Skip();
return false;
}
}

public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOptions options)
{
throw new NotSupportedException();
}
}
}
Loading
Loading