Skip to content

Commit

Permalink
Convert StringOrArrayConverter to generic version
Browse files Browse the repository at this point in the history
  • Loading branch information
kirill-abblix committed Jul 2, 2024
1 parent 18ab860 commit b25ef8c
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 22 deletions.
2 changes: 1 addition & 1 deletion Abblix.Oidc.Server/Model/AuthorizationRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public record AuthorizationRequest
/// resource.
/// </summary>
[JsonPropertyName(Parameters.Resource)]
[JsonConverter(typeof(StringOrArrayConverter))]
[JsonConverter(typeof(SingleOrArrayConverter<Uri>))]
public Uri[]? Resources { get; set; }

public static class Parameters
Expand Down
9 changes: 2 additions & 7 deletions Abblix.Oidc.Server/Model/TokenRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public static class Parameters
/// Defined in RFC 8707.
/// </remarks>
[JsonPropertyName(Parameters.Resource)]
[JsonConverter(typeof(StringOrArrayConverter))]
[JsonConverter(typeof(SingleOrArrayConverter<Uri>))]
public Uri[]? Resources { get; set; }

/// <summary>
Expand All @@ -94,12 +94,7 @@ public static class Parameters
/// The scope of the access request, expressed as a list of space-delimited, case-sensitive strings.
/// </summary>
[JsonPropertyName(Parameters.Scope)]
[AllowedValues(
Scopes.OpenId,
Scopes.Profile,
Scopes.Email,
Scopes.Phone,
Scopes.OfflineAccess)]
[AllowedValues(Scopes.OpenId, Scopes.Profile, Scopes.Email, Scopes.Phone, Scopes.OfflineAccess)]
public string[] Scope { get; set; } = Array.Empty<string>();

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@

namespace Abblix.Utils.UnitTests;

public class StringOrArrayConverterTests
public class SingleOrArrayConverterTests
{
private readonly StringOrArrayConverter _converter = new();
private readonly SingleOrArrayConverter<string> _converter = new();

[Theory]
[InlineData("\"singleString\"", new[] { "singleString" })]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
// CONTACT: For license inquiries or permissions, contact Abblix LLP at
// info@abblix.com

using System.Collections.Generic;

namespace Abblix.Utils.Json;

using System;
Expand All @@ -32,7 +30,7 @@ namespace Abblix.Utils.Json;
/// A JSON converter that handles deserialization and serialization of a JSON value
/// that could either be a single string or an array of strings.
/// </summary>
public class StringOrArrayConverter : JsonConverter<string[]>
public class SingleOrArrayConverter<T> : JsonConverter<T[]>
{
/// <summary>
/// Reads and converts the JSON to a string array.
Expand All @@ -45,15 +43,19 @@ public class StringOrArrayConverter : JsonConverter<string[]>
/// <returns>An array of strings parsed from the JSON input.</returns>
/// <exception cref="JsonException">Thrown if an unexpected token type is encountered.</exception>

public override string[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
public override T[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var elementType = typeof(T);
var converter = (JsonConverter<T>)options.GetConverter(elementType)
?? throw new JsonException($"No converter found for {elementType}");

switch (reader.TokenType)
{
case JsonTokenType.Null:
return null;

case JsonTokenType.String:
return new[] { ReadStringFrom(reader) };
return new[] { ReadFrom(ref reader, elementType, converter, options) };

case JsonTokenType.StartArray:
break;
Expand All @@ -62,7 +64,7 @@ public class StringOrArrayConverter : JsonConverter<string[]>
throw new JsonException("Unexpected token type.");
}

var values = new List<string>();
var values = new List<T>();
while (reader.Read())
{
switch (reader.TokenType)
Expand All @@ -71,7 +73,7 @@ public class StringOrArrayConverter : JsonConverter<string[]>
break;

case JsonTokenType.String:
values.Add(ReadStringFrom(reader));
values.Add(ReadFrom(ref reader, elementType, converter, options));
break;

default:
Expand All @@ -80,8 +82,11 @@ public class StringOrArrayConverter : JsonConverter<string[]>
}
return values.ToArray();

static string ReadStringFrom(Utf8JsonReader reader)
=> reader.GetString() ?? throw new JsonException("Null values are not allowed");
static T ReadFrom(ref Utf8JsonReader reader, Type elementType, JsonConverter<T> converter, JsonSerializerOptions options)
{
return converter.Read(ref reader, elementType, options)
?? throw new JsonException("Null values are not allowed");
}
}

/// <summary>
Expand All @@ -93,8 +98,12 @@ static string ReadStringFrom(Utf8JsonReader reader)
/// <param name="value">The string array to write.</param>
/// <param name="options">Options for the serializer.</param>
/// <exception cref="ArgumentNullException">Thrown if the writer or value is null.</exception>
public override void Write(Utf8JsonWriter writer, string[]? value, JsonSerializerOptions options)
public override void Write(Utf8JsonWriter writer, T[]? value, JsonSerializerOptions options)
{
var elementType = typeof(T);
var converter = (JsonConverter<T>)options.GetConverter(elementType)
?? throw new JsonException($"No converter found for {elementType}");

if (value == null)
{
writer.WriteNullValue();
Expand All @@ -104,14 +113,14 @@ public override void Write(Utf8JsonWriter writer, string[]? value, JsonSerialize
switch (value.Length)
{
case 1:
writer.WriteStringValue(value[0]);
converter.Write(writer, value[0], options);
break;

default:
writer.WriteStartArray();
foreach (var item in value)
{
writer.WriteStringValue(item);
converter.Write(writer, item, options);
}
writer.WriteEndArray();
break;
Expand Down

0 comments on commit b25ef8c

Please sign in to comment.