V11 / ca6f28eff240
ProjectJson.cs
Lilith/Core/Projects/ProjectJson.cs
Changed in this versionCS
using System.Text.Json;
using System.Text.Json.Nodes;
namespace Lilith.Core.Projects;
internal static class ProjectJson
{
// Internal data transport/files only; presentation hosts must HTML-encode source when rendering it.
internal static readonly JsonSerializerOptions Options = new() { PropertyNameCaseInsensitive = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping, WriteIndented = true };
internal static T Parse<T>(string text)
{
text = text.Trim();
if (text.StartsWith("```", StringComparison.Ordinal))
{
int newline = text.IndexOf('\n');
if (newline < 0 || !text.EndsWith("```", StringComparison.Ordinal)) throw new InvalidDataException("Incomplete JSON fence.");
text = text[(newline + 1)..^3].Trim();
}
return JsonSerializer.Deserialize<T>(text, Options) ?? throw new InvalidDataException("Missing project JSON.");
}
internal static string Serialize<T>(T value) => JsonSerializer.Serialize(value, Options);
internal static ProjectArchitecture Architecture(string text)
{
var raw = Parse<JsonElement>(text);
var node = JsonNode.Parse(raw.GetRawText()) as JsonObject ?? throw new InvalidDataException("Architecture must be an object.");
if (node["contract"] is JsonObject or JsonArray)
node["contract"] = node["contract"]!.ToJsonString();
return Parse<ProjectArchitecture>(node.ToJsonString());
}
}