74 lines
3.7 KiB
C#
74 lines
3.7 KiB
C#
using System.Globalization;
|
|
|
|
namespace LehrerApp.Templating;
|
|
|
|
public static class TemplateDataResolver
|
|
{
|
|
public static IReadOnlyList<string> ValidateConstants(TemplateManifest manifest)
|
|
{
|
|
var issues = new List<string>();
|
|
var definitions = manifest.Placeholders.GroupBy(x => x.Name, StringComparer.Ordinal)
|
|
.ToDictionary(x => x.Key, x => x.First(), StringComparer.Ordinal);
|
|
foreach (var constant in manifest.Placeholders.Where(x => x.IsConstant))
|
|
{
|
|
try
|
|
{
|
|
ConstantValue(constant);
|
|
if (constant.Type is not (PlaceholderType.Text or PlaceholderType.Multiline)) continue;
|
|
foreach (var reference in TemplateRichText.UsedPlaceholders(constant.ConstantValue ?? ""))
|
|
{
|
|
if (!definitions.TryGetValue(reference, out var target))
|
|
issues.Add($"Konstanter Text „{constant.Name}“ verwendet den nicht deklarierten Platzhalter „{reference}“.");
|
|
else if (target.IsConstant)
|
|
issues.Add($"Konstanter Text „{constant.Name}“ darf nur externe Platzhalter verwenden; „{reference}“ ist ebenfalls konstant.");
|
|
else if (target.Type is not (PlaceholderType.Text or PlaceholderType.Multiline
|
|
or PlaceholderType.Date or PlaceholderType.Number))
|
|
issues.Add($"Eingebetteter Platzhalter „{reference}“ hat keinen textuell darstellbaren Typ.");
|
|
}
|
|
}
|
|
catch (InvalidDataException ex) { issues.Add(ex.Message); }
|
|
}
|
|
return issues;
|
|
}
|
|
|
|
public static IReadOnlyDictionary<string, PlaceholderValue> Resolve(TemplateManifest manifest,
|
|
IReadOnlyDictionary<string, PlaceholderValue> externalValues)
|
|
{
|
|
var result = new Dictionary<string, PlaceholderValue>(externalValues, StringComparer.Ordinal);
|
|
foreach (var definition in manifest.Placeholders.Where(x => x.IsConstant))
|
|
result[definition.Name] = ConstantValue(definition);
|
|
return result;
|
|
}
|
|
|
|
public static PlaceholderValue ConstantValue(PlaceholderDefinition definition)
|
|
{
|
|
var raw = definition.ConstantValue ?? "";
|
|
return definition.Type switch
|
|
{
|
|
PlaceholderType.Text => new TextValue(raw),
|
|
PlaceholderType.Multiline => new MultilineValue(raw),
|
|
PlaceholderType.Date => new DateValue(ParseDate(definition, raw)),
|
|
PlaceholderType.Number => new NumberValue(ParseNumber(definition, raw)),
|
|
_ => throw new InvalidDataException(
|
|
$"Platzhalter „{definition.Name}“ vom Typ {definition.Type} kann keinen konstanten Textwert verwenden."),
|
|
};
|
|
}
|
|
|
|
private static DateOnly ParseDate(PlaceholderDefinition definition, string raw)
|
|
{
|
|
if (DateOnly.TryParse(raw, CultureInfo.InvariantCulture, DateTimeStyles.None, out var date)
|
|
|| DateOnly.TryParse(raw, CultureInfo.GetCultureInfo("de-DE"), DateTimeStyles.None, out date)) return date;
|
|
throw Error(definition, "Datum, z. B. 2026-08-30");
|
|
}
|
|
|
|
private static decimal ParseNumber(PlaceholderDefinition definition, string raw)
|
|
{
|
|
if (decimal.TryParse(raw, NumberStyles.Number, CultureInfo.InvariantCulture, out var number)
|
|
|| decimal.TryParse(raw, NumberStyles.Number, CultureInfo.GetCultureInfo("de-DE"), out number)) return number;
|
|
throw Error(definition, "Zahl");
|
|
}
|
|
|
|
private static InvalidDataException Error(PlaceholderDefinition definition, string expected) =>
|
|
new($"Konstanter Wert für „{definition.Name}“ ist ungültig; erwartet wird: {expected}.");
|
|
}
|