56 lines
1.7 KiB
C#
56 lines
1.7 KiB
C#
using System.Text.Json;
|
|
using System.Text.Json.Nodes;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace HSchool.Content;
|
|
|
|
/// <summary>JSON with comments and trailing commas — the format of every def, patch, locale and map file.</summary>
|
|
public static class Jsonc
|
|
{
|
|
public static JsonSerializerOptions SerializerOptions { get; } = new()
|
|
{
|
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
|
PropertyNameCaseInsensitive = true,
|
|
AllowTrailingCommas = true,
|
|
WriteIndented = true,
|
|
Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) },
|
|
};
|
|
|
|
public static JsonDocumentOptions DocumentOptions { get; } = new()
|
|
{
|
|
// Skip, not Allow: JsonDocument will not store comments. The files may still contain them.
|
|
CommentHandling = JsonCommentHandling.Skip,
|
|
AllowTrailingCommas = true,
|
|
};
|
|
|
|
public static JsonNode Parse(string text, string? source = null)
|
|
{
|
|
try
|
|
{
|
|
var node = JsonNode.Parse(text, documentOptions: DocumentOptions);
|
|
if (node is null)
|
|
{
|
|
throw new ContentLoadException(source is null ? "JSONC was empty." : $"JSONC {source} was empty.");
|
|
}
|
|
|
|
return node;
|
|
}
|
|
catch (JsonException ex)
|
|
{
|
|
var where = source is null ? "JSONC" : $"JSONC {source}";
|
|
throw new ContentLoadException($"{where} is not valid: {ex.Message}", ex);
|
|
}
|
|
}
|
|
|
|
public static T Deserialize<T>(JsonNode node)
|
|
{
|
|
var value = node.Deserialize<T>(SerializerOptions);
|
|
if (value is null)
|
|
{
|
|
throw new ContentLoadException($"Could not read a {typeof(T).Name} from JSONC.");
|
|
}
|
|
|
|
return value;
|
|
}
|
|
}
|