Adding per object validation

This commit is contained in:
christopher.bell@i3-corps.com 2025-07-17 10:14:44 -05:00
parent 69df933609
commit f00bde7e24
12 changed files with 137 additions and 47 deletions

View File

@ -1,6 +1,7 @@
using Spectre.Console; using Spectre.Console;
using SessionZero.SzfLib.Parser; using SessionZero.SzfLib.Parser;
using System.IO; using System.IO;
using SessionZero.SzfLib.Helpers;
void PrintSection(dynamic section, int indent = 0) void PrintSection(dynamic section, int indent = 0)
{ {
@ -55,19 +56,27 @@ if (!File.Exists(filePath))
string szfContent = File.ReadAllText(filePath); string szfContent = File.ReadAllText(filePath);
var parser = new SzfParser(); var parser = new SzfParser();
var szfObject = parser.Parse(szfContent); try
if (szfObject == null)
{ {
AnsiConsole.MarkupLine("[red]Failed to parse SZF file.[/]"); var szfObject = parser.Parse(szfContent);
return;
if (szfObject == null)
{
AnsiConsole.MarkupLine("[red]Failed to parse SZF file.[/]");
return;
}
AnsiConsole.MarkupLine($"[bold]SZF Type:[/] {szfObject.SzfType}");
AnsiConsole.MarkupLine($"[bold]SZF Version:[/] {szfObject.SzfVersion}");
AnsiConsole.MarkupLine($"[bold]Number of Sections:[/] {szfObject.Sections.Count}");
foreach (var section in szfObject.Sections)
{
PrintSection(section);
}
}
catch (SzfError ex)
{
Console.WriteLine($"Szf Validation Error: {ex.Message}");
} }
AnsiConsole.MarkupLine($"[bold]SZF Type:[/] {szfObject.SzfType}");
AnsiConsole.MarkupLine($"[bold]SZF Version:[/] {szfObject.SzfVersion}");
AnsiConsole.MarkupLine($"[bold]Number of Sections:[/] {szfObject.Sections.Count}");
foreach (var section in szfObject.Sections)
{
PrintSection(section);
}

View File

@ -0,0 +1,18 @@
namespace SessionZero.SzfLib.Helpers;
public class SzfError : Exception
{
public bool IsValid { get; set; } = true;
public string Message { get; set; } = string.Empty;
public void AddError(string message)
{
Message += message + "\r\n";
IsValid = false;
}
public override string ToString()
{
return $"Valid: {IsValid}, Message: {Message}";
}
}

View File

@ -16,4 +16,16 @@ public static class SzfHelper
return obj.IsAbstract || obj.IsInterface ? null : obj; return obj.IsAbstract || obj.IsInterface ? null : obj;
} }
public static SzfError BasicSzfValidation(ISzfObject obj)
{
SzfError result = new SzfError();
var metadataSection = obj.Sections.FirstOrDefault(s => s.Name == "Metadata");
if (metadataSection is null) result.AddError("No metadata section found");
if (obj.GetMetadataField("Name") == string.Empty) result.AddError("No metadata field name found");
return result;
}
} }

View File

@ -1,3 +1,4 @@
using SessionZero.SzfLib.Helpers;
using SessionZero.SzfLib.Parser; using SessionZero.SzfLib.Parser;
namespace SessionZero.SzfLib.Objects; namespace SessionZero.SzfLib.Objects;
@ -12,5 +13,9 @@ public interface ISzfObject
public string GetFieldValue(string sectionName, string fieldName); public string GetFieldValue(string sectionName, string fieldName);
public string FindFieldValueInSection(SzfSection section, string[] path, int depth, string fieldName); public string FindFieldValueInSection(SzfSection section, string[] path, int depth, string fieldName);
public ISzfObject? Parse(); /// <summary>
///
/// </summary>
/// <returns></returns>
public SzfError Validate();
} }

View File

@ -1,7 +1,13 @@
using SessionZero.SzfLib.Helpers;
namespace SessionZero.SzfLib.Objects; namespace SessionZero.SzfLib.Objects;
[SzfObject("character")] [SzfObject("character")]
public class SzfCharacter : SzfObject, ISzfCharacter public class SzfCharacter : SzfObject, ISzfCharacter
{ {
public override string SzfType { get; set; } = "character"; public override string SzfType { get; set; } = "character";
public override SzfError Validate()
{
throw new NotImplementedException();
}
} }

View File

@ -1,7 +1,13 @@
using SessionZero.SzfLib.Helpers;
namespace SessionZero.SzfLib.Objects; namespace SessionZero.SzfLib.Objects;
[SzfObject("character_template")] [SzfObject("character_template")]
public class SzfCharacterTemplate : SzfObject, ISzfCharacterTemplate public class SzfCharacterTemplate : SzfObject, ISzfCharacterTemplate
{ {
public override string SzfType { get; set; } = "character_template"; public override string SzfType { get; set; } = "character_template";
public override SzfError Validate()
{
throw new NotImplementedException();
}
} }

View File

@ -1,7 +1,25 @@
using SessionZero.SzfLib.Helpers;
using SessionZero.SzfLib.Parser;
namespace SessionZero.SzfLib.Objects; namespace SessionZero.SzfLib.Objects;
[SzfObject("dataset")] [SzfObject("dataset")]
public class SzfDataset : SzfObject, ISzfDataset public class SzfDataset : SzfObject, ISzfDataset
{ {
public override string SzfType { get; set; } = "dataset"; public override string SzfType { get; set; } = "dataset";
}
public override SzfError Validate()
{
var result = SzfHelper.BasicSzfValidation(this);
if (GetMetadataField("Type") == string.Empty) result.AddError("Metadata field `Type` is missing or empty");
foreach (var entry in Sections.Where(entry => GetFieldValue(entry.Name, "Name") == string.Empty))
{
result.AddError($"Entry {entry.Name}'s `Name` field is missing or empty");
}
return result;
}
}

View File

@ -1,3 +1,4 @@
using SessionZero.SzfLib.Helpers;
using SessionZero.SzfLib.Parser; using SessionZero.SzfLib.Parser;
namespace SessionZero.SzfLib.Objects; namespace SessionZero.SzfLib.Objects;
@ -13,9 +14,10 @@ public abstract class SzfObject : ISzfObject
/// Handles specific parsing logic for the SzfObject that overrides this method. /// Handles specific parsing logic for the SzfObject that overrides this method.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual ISzfObject? Parse() public virtual SzfError Validate()
{ {
return this; var result = SzfHelper.BasicSzfValidation(this);
return result;
} }
/// <summary> /// <summary>

View File

@ -0,0 +1,13 @@
namespace SessionZero.SzfLib.Parser;
public class SzfField(string name, SzfFieldType type)
{
public string Name { get; set; } = name;
public SzfFieldType SzfType { get; set; } = type;
public string? Value { get; set; }
public bool Validate()
{
throw new NotImplementedException();
}
}

View File

@ -0,0 +1,13 @@
namespace SessionZero.SzfLib.Parser;
public enum SzfFieldType
{
Text,
TextField,
Number,
Bool,
Calculated,
System,
EntryReference,
EntryReferenceList,
}

View File

@ -7,12 +7,15 @@ namespace SessionZero.SzfLib.Parser;
public class SzfParser : ISzfParser public class SzfParser : ISzfParser
{ {
/// <summary> /// <summary>
/// Parses the given SZF content and returns the corresponding ISzfObject. /// Tries to parse an ISzfObject
/// </summary> /// </summary>
/// <param name="szfContent"></param> /// <param name="szfContent"></param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="SzfError"></exception>
public ISzfObject? Parse(string szfContent) public ISzfObject? Parse(string szfContent)
{ {
SzfError result = new();
var lines = szfContent.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); var lines = szfContent.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
string szfObjectTypeName = string.Empty; string szfObjectTypeName = string.Empty;
@ -72,11 +75,15 @@ public class SzfParser : ISzfParser
{ {
szfObject.Sections.Add(section); szfObject.Sections.Add(section);
} }
result = szfObject.Validate();
return szfObject.Parse() ?? szfObject; if (result.IsValid) return szfObject;
Console.WriteLine(result.Message);
} }
return null; throw result;
} }
public ISzfObject? Parse(ISzfFile file) public ISzfObject? Parse(ISzfFile file)
@ -143,31 +150,4 @@ public class SzfParser : ISzfParser
} }
}
public class SzfSection(string name)
{
public string Name { get; set; } = name;
public Dictionary<string, SzfField> Fields { get; set; } = new();
public Dictionary<string, SzfSection> Subsections { get; set; } = new();
}
public class SzfField(string name, SzfFieldType type)
{
public string Name { get; set; } = name;
public SzfFieldType SzfType { get; set; } = type;
public string? Value { get; set; }
}
public enum SzfFieldType
{
Text,
TextField,
Number,
Bool,
Calculated,
System,
EntryReference,
EntryReferenceList,
} }

View File

@ -0,0 +1,8 @@
namespace SessionZero.SzfLib.Parser;
public class SzfSection(string name)
{
public string Name { get; set; } = name;
public Dictionary<string, SzfField> Fields { get; set; } = new();
public Dictionary<string, SzfSection> Subsections { get; set; } = new();
}