using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.Json;
namespace MonoGame.Extended.Serialization.Json;
///
/// Provides extension methods for working with .
///
public static class Utf8JsonReaderExtensions
{
private static readonly Dictionary> s_stringParsers = new Dictionary>
{
{typeof(int), s => int.Parse(s, CultureInfo.InvariantCulture.NumberFormat)},
{typeof(float), s => float.Parse(s, CultureInfo.InvariantCulture.NumberFormat)},
{typeof(HslColor), s => HslColor.FromRgb(ColorExtensions.FromHex(s))}
};
///
/// Reads a multi-dimensional JSON array and converts it to an array of the specified type.
///
/// The type of the array elements.
/// The to read from.
/// An object that specifies serialization options to use.
/// An array of the specified type.
/// Thrown when the token type is not supported.
public static T[] ReadAsMultiDimensional(this ref Utf8JsonReader reader, JsonSerializerOptions options)
{
var tokenType = reader.TokenType;
switch (tokenType)
{
case JsonTokenType.StartArray:
return reader.ReadAsJArray(options);
case JsonTokenType.String:
return reader.ReadAsDelimitedString();
case JsonTokenType.Number:
return reader.ReadAsSingleValue(options);
default:
throw new NotSupportedException($"{tokenType} is not currently supported in the multi-dimensional parser");
}
}
private static T[] ReadAsSingleValue(this ref Utf8JsonReader reader, JsonSerializerOptions options)
{
var token = JsonDocument.ParseValue(ref reader).RootElement;
var value = JsonSerializer.Deserialize(token.GetRawText(), options);
return new T[] { value };
}
private static T[] ReadAsJArray(this ref Utf8JsonReader reader, JsonSerializerOptions options)
{
var items = new List();
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
{
if (reader.TokenType == JsonTokenType.EndArray)
{
break;
}
items.Add(JsonSerializer.Deserialize(ref reader, options));
}
return items.ToArray();
}
private static T[] ReadAsDelimitedString(this ref Utf8JsonReader reader)
{
var value = reader.GetString();
if (string.IsNullOrEmpty(value))
{
return Array.Empty();
}
Span values = value.Split(' ');
var result = new T[values.Length];
var parser = s_stringParsers[typeof(T)];
for (int i = 0; i < values.Length; i++)
{
result[i] = (T)parser(values[i]);
}
return result;
}
}