using System.Text.Json; using System.Text.Json.Nodes; using System.Text.Json.Serialization; namespace HSchool.Content; /// JSON with comments and trailing commas — the format of every def, patch, locale and map file. 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(JsonNode node) { var value = node.Deserialize(SerializerOptions); if (value is null) { throw new ContentLoadException($"Could not read a {typeof(T).Name} from JSONC."); } return value; } }