using System;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Terminal.Gui {
///
/// Json converter for . Supports
/// A string as one of:
/// - unicode char (e.g. "☑")
/// - U+hex format (e.g. "U+2611")
/// - \u format (e.g. "\\u2611")
/// A number
/// - The unicode code in decimal
///
internal class RuneJsonConverter : JsonConverter {
public override Rune Read (ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String) {
var value = reader.GetString ();
if (value.StartsWith ("U+", StringComparison.OrdinalIgnoreCase) || value.StartsWith ("\\u")) {
try {
uint result = uint.Parse (value [2..^0], System.Globalization.NumberStyles.HexNumber);
return new Rune (result);
} catch (FormatException e) {
throw new JsonException ($"Invalid Rune format: {value}.", e);
}
} else {
return new Rune (value [0]);
}
throw new JsonException ($"Invalid Rune format: {value}.");
} else if (reader.TokenType == JsonTokenType.Number) {
return new Rune (reader.GetUInt32 ());
}
throw new JsonException ($"Unexpected StartObject token when parsing Rune: {reader.TokenType}.");
}
public override void Write (Utf8JsonWriter writer, Rune value, JsonSerializerOptions options)
{
// HACK: Writes a JSON comment in addition to the glyph to ease debugging.
// Technically, JSON comments are not valid, but we use relaxed decoding
// (ReadCommentHandling = JsonCommentHandling.Skip)
writer.WriteCommentValue ($"(U+{value.Value:X4})");
writer.WriteRawValue ($"\"{value}\"");
}
}
#pragma warning restore 1591
}