← All source files

V17 / d6d373561692

ProjectJson.cs

Lilith/Core/Projects/ProjectJson.cs

Unchanged from the preceding version
CS
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());
    }
}