This repository has been archived on 2026-01-20. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
SessionZero-Client/SessionZero/Data/Sztl/SztlParser.cs

152 lines
4.6 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Tomlyn;
using Tomlyn.Model;
namespace SessionZero.Data.Sztl;
public static class SztlParser
{
public static SzTemplate ParseTemplate(string tomlText)
{
var doc = Toml.ToModel(tomlText);
if (!doc.ContainsKey("metadata") || doc["metadata"] is not TomlTable metadata)
{
throw new Exception("Template missing the [metadata] section");
}
// Determine template type and fill metadata
string templateType = metadata.TryGetValue("template_type", out var tempTypeVal)
? tempTypeVal?.ToString() ?? throw new Exception("Template missing template_type metadata")
: throw new Exception("Template missing template_type metadata");
SzTemplate template = templateType switch
{
"data" => new SzDataObjectTemplate(),
_ => throw new NotImplementedException($"Unknown template_type '{templateType}'")
};
if (metadata.TryGetValue("id", out var idVal)) template.Id = idVal?.ToString()!;
else throw new Exception("Template missing id metadata");
if (metadata.TryGetValue("uuid", out var uuidVal)) template.Uuid = uuidVal?.ToString()!;
else throw new Exception("Template missing uuid metadata");
if (metadata.TryGetValue("version", out var versionVal)) template.Version = versionVal?.ToString()!;
else throw new Exception("Template missing version metadata");
if (metadata.TryGetValue("compatible_systems", out var compSysVal) && compSysVal is string[] arr)
template.CompatibleSystems = arr.ToList();
if (metadata.TryGetValue("description", out var descVal))
template.Description = descVal?.ToString()!;
else throw new Exception("Template missing description metadata");
template.ParseAdditionalMetaData(doc);
// Process all other tables as fields or groups
ProcessTable(template, doc);
return template;
}
private static void InsertFieldIntoGroup(SzTemplate template, string[] pathParts, TomlTable table)
{
var groupDict = template.SubGroups;
SztlFieldGroup currentGroup = null!;
for (int i = 0; i < pathParts.Length - 1; i++)
{
var part = pathParts[i];
if (!groupDict.TryGetValue(part, out var grp))
{
grp = new SztlFieldGroup { Id = part };
groupDict[part] = grp;
}
currentGroup = grp;
groupDict = grp.SubGroups;
}
var fieldId = pathParts[^1];
var leafTable = table;
if (table.TryGetValue(fieldId, out var possibleLeaf) && possibleLeaf is TomlTable t)
{
leafTable = t;
}
var field = ParseFieldFromTable(fieldId, leafTable);
currentGroup.Fields[fieldId] = field;
}
private static SztlField ParseFieldFromTable(string id, TomlTable table)
{
var field = new SztlField
{
Id = id
};
if (!table.TryGetValue("type", out var tVal))
{
throw new Exception($"Field '{id}' missing type");
}
var typeStr = tVal?.ToString() ?? throw new Exception($"Field '{id}' has null type");
if (!Enum.TryParse<SzFieldType>(typeStr, ignoreCase: true, out var ftype))
{
throw new Exception($"Field '{id}' has unknown type '{typeStr}'");
}
field.Type = ftype;
if (table.TryGetValue("default_value", out var dVal))
{
field.DefaultValue = dVal;
}
if (ftype == SzFieldType.Textblock)
{
field.IsTextBlock = true;
}
return field;
}
private static void ProcessTable(SzTemplate template, TomlTable table, string parentPath = "")
{
foreach (var (key, value) in table)
{
if (key == "metadata") continue;
var path = string.IsNullOrEmpty(parentPath) ? key : $"{parentPath}.{key}";
if (value is TomlTable t)
{
if (t.ContainsKey("type"))
{
var field = ParseFieldFromTable(key, t);
if (string.IsNullOrEmpty(parentPath))
{
template.Fields[key] = field;
}
else
{
InsertFieldIntoGroup(template, path.Split('.'), t);
}
}
else
{
ProcessTable(template, t, path);
}
}
}
}
}