File size: 2,485 Bytes
3ce1a40 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | using System.Text.Json;
using System.Text.Json.Serialization;
using Repoverse.Core.Model;
namespace Repoverse.Core.Generation;
/// <summary>
/// Hand-authored world design (§83). Overrides augment procedural output; any repo
/// not listed is generated normally.
/// </summary>
public sealed class Overrides
{
public sealed record Entry
{
public SemanticCategory? Category { get; init; }
public District? District { get; init; }
public BuildingArchetype? Archetype { get; init; }
public bool Landmark { get; init; }
}
private readonly Dictionary<string, Entry> _entries;
public string Source { get; }
public Overrides(IReadOnlyDictionary<string, Entry> entries, string source)
{
_entries = entries.ToDictionary(kv => kv.Key.ToLowerInvariant(), kv => kv.Value);
Source = source;
}
public static Overrides Empty { get; } = new(new Dictionary<string, Entry>(), "(none)");
public static Overrides Load(string path)
{
var entries = JsonSerializer.Deserialize<Dictionary<string, Entry>>(File.ReadAllText(path), Json.Options)
?? throw new InvalidDataException($"Override file '{path}' is empty.");
return new Overrides(entries, Path.GetFileName(path));
}
private Entry? Get(RepoId id) => _entries.GetValueOrDefault(id.Key);
public SemanticCategory? Category(RepoId id) => Get(id)?.Category;
public District? District(RepoId id) => Get(id)?.District;
public BuildingArchetype? Archetype(RepoId id) => Get(id)?.Archetype;
public bool Landmark(RepoId id) => Get(id)?.Landmark ?? false;
}
/// <summary>Shared serializer settings: enums as strings so manifests stay human-readable and diffable.</summary>
public static class Json
{
public static JsonSerializerOptions Options { get; } = new()
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase), new RepoIdConverter() },
};
private sealed class RepoIdConverter : JsonConverter<RepoId>
{
public override RepoId Read(ref Utf8JsonReader reader, Type t, JsonSerializerOptions o) => RepoId.Parse(reader.GetString()!);
public override void Write(Utf8JsonWriter writer, RepoId value, JsonSerializerOptions o) => writer.WriteStringValue($"{value.Owner}/{value.Name}");
}
}
|