diff --git a/SessionZero.sln.DotSettings.user b/SessionZero.sln.DotSettings.user new file mode 100644 index 0000000..80cfb75 --- /dev/null +++ b/SessionZero.sln.DotSettings.user @@ -0,0 +1,2 @@ + + ForceIncluded \ No newline at end of file diff --git a/SzCli/Program.cs b/SzCli/Program.cs index bf462bd..56a6eab 100644 --- a/SzCli/Program.cs +++ b/SzCli/Program.cs @@ -16,7 +16,10 @@ public class Program Test.CreateTestData(); + var dataset = SZ.SzDataHandler.LoadDataset("test-dataset"); var dataTemplate = SZ.SzDataHandler.LoadTemplate("szcore-item-basic"); - _logger.Log($"Test - {dataTemplate?.DataObjectType ?? "Template was null"}"); + + var evalResult = SZ.SzEvaluator.EvaluateDataObject(dataset.DataObjects["test"], dataTemplate); + _logger.Log($"Evaluation test -- Pass?: {evalResult.Pass} {(evalResult.Errors == "" ? "" : (" - Errors: " + evalResult.Errors))}"); } -} \ No newline at end of file +} diff --git a/SzCli/Test.cs b/SzCli/Test.cs index 961b9c1..316de64 100644 --- a/SzCli/Test.cs +++ b/SzCli/Test.cs @@ -48,7 +48,7 @@ public static class Test var testField = new SzField() { - Id = "value", + Id = "cost", FieldType = SzFieldType.Number, Value = "200" }; @@ -65,4 +65,4 @@ public static class Test SZ.Logger.Log(" -- CreateTestData Test: Success --"); } -} \ No newline at end of file +} diff --git a/SzCore/DataObjects/SzFieldType.cs b/SzCore/DataObjects/SzFieldType.cs index 5dfa1df..8e24fad 100644 --- a/SzCore/DataObjects/SzFieldType.cs +++ b/SzCore/DataObjects/SzFieldType.cs @@ -2,5 +2,5 @@ namespace SzCore.DataObjects; public enum SzFieldType { - Text, Number, Bool, Formula, Ref + Text, Number, Bool, Formula, Reference } \ No newline at end of file diff --git a/SzCore/SZ.cs b/SzCore/SZ.cs index 3b732b9..80f268d 100644 --- a/SzCore/SZ.cs +++ b/SzCore/SZ.cs @@ -11,6 +11,7 @@ public static class SZ public static readonly SzParser SzParser = new(); public static readonly SzDataHandler SzDataHandler = new(); + public static readonly SzEvaluator SzEvaluator = new(); public static ISzFileManager LocalFileManager { diff --git a/SzCore/SzCore.csproj b/SzCore/SzCore.csproj index f46f471..7a0f814 100644 --- a/SzCore/SzCore.csproj +++ b/SzCore/SzCore.csproj @@ -6,7 +6,9 @@ enable - + + + diff --git a/SzCore/SzEvaluator.cs b/SzCore/SzEvaluator.cs new file mode 100644 index 0000000..e8a5c7d --- /dev/null +++ b/SzCore/SzEvaluator.cs @@ -0,0 +1,102 @@ +using System.Data; +using System.Text; +using SzCore.DataObjects; + +namespace SzCore; + +public class SzEvaluator +{ + public SzEvaluationResult EvaluateDataObject(SzDataObject dataObject, SzDataObjectTemplate template) + { + if (dataObject is null || template is null) return new SzEvaluationResult(false, "dataObject or template is null"); + + var errors = new StringBuilder(); + + foreach (var (key, templateField) in template.TemplateFields) + { + if (!dataObject.Fields.TryGetValue(key, out var matchingField)) + { + errors.AppendLine($"Missing required field: '{key}'"); + continue; + } + + var templateMatchResult = DoesFieldMatchTemplateField(matchingField, templateField); + if (!templateMatchResult.Pass) errors.Append(templateMatchResult.Errors); + + var evalResult = EvaluateFieldValue(matchingField); + if (!evalResult.Pass) errors.Append(evalResult.Errors); + } + + foreach (var objectFieldKey in dataObject.Fields.Keys) + { + if (!template.TemplateFields.ContainsKey(objectFieldKey)) + { + errors.AppendLine($"DataObject contains extra field '{objectFieldKey}' not found in template"); + } + } + + var errString = errors.ToString().Trim(); + return new SzEvaluationResult(string.IsNullOrEmpty(errString), string.IsNullOrEmpty(errString) ? "" : errString); + } + + public SzEvaluationResult DoesFieldMatchTemplateField(SzField field, SzTemplateField templateField) + { + var errors = new StringBuilder(); + + if (field.Id != templateField.Id) errors.AppendLine($"Field ID mismatch for '{field.Id}': Expected {templateField.Id}"); + if (field.FieldType != templateField.FieldType) errors.AppendLine($"Field '{field.Id}' type mismatch: Expected {templateField.FieldType}, got {field.FieldType}"); + if (field.IsList != templateField.IsList) errors.AppendLine($"Field '{field.Id}' IsList mismatch: Expected {templateField.IsList}"); + + var errString = errors.ToString().Trim(); + return new SzEvaluationResult(string.IsNullOrEmpty(errString), errString); + } + + public SzEvaluationResult EvaluateFieldValue(SzField field) + { + if (string.IsNullOrWhiteSpace(field.Value)) + return new SzEvaluationResult(true, ""); + + var errors = new StringBuilder(); + + switch (field.FieldType) + { + case SzFieldType.Text: + break; + + case SzFieldType.Number: + if (!float.TryParse(field.Value, out _)) + { + errors.AppendLine($"Value '{field.Value}' in field '{field.Id}' is not a valid Number"); + } + break; + + case SzFieldType.Bool: + if (!bool.TryParse(field.Value, out _)) + { + errors.AppendLine($"Value '{field.Value}' in field '{field.Id}' is not a valid Boolean"); + } + break; + + case SzFieldType.Formula: + errors.AppendLine($"Formula field type is not implemented yet. Field: {field.Id}"); + break; + + case SzFieldType.Reference: + errors.AppendLine($"Reference field type is not implemented yet. Field: {field.Id}"); + break; + + default: + errors.AppendLine($"Unsupported FieldType '{field.FieldType}' for field '{field.Id}'"); + break; + } + + var errString = errors.ToString().Trim(); + return new SzEvaluationResult(string.IsNullOrEmpty(errString), errString); + } +} + +public class SzEvaluationResult(bool pass, string errors = "None") +{ + public bool Pass = pass; + public string Errors = errors; +} diff --git a/SzCore/SzParser.cs b/SzCore/SzParser.cs index bd667de..3358e2b 100644 --- a/SzCore/SzParser.cs +++ b/SzCore/SzParser.cs @@ -1,19 +1,22 @@ -using System.Text.Json; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; using SzCore.DataObjects; namespace SzCore; public class SzParser { - - private readonly JsonSerializerOptions _jsonOptions = new() { WriteIndented = true }; + private readonly JsonSerializerSettings _jsonSettings = new() + { + Formatting = Formatting.Indented, + Converters = { new StringEnumConverter() } + }; public string SerializeDatasetToJson(SzDataset dataset) { try { - var jsonString = JsonSerializer.Serialize(dataset, _jsonOptions); - return jsonString; + return JsonConvert.SerializeObject(dataset, _jsonSettings); } catch (JsonException e) { @@ -25,8 +28,7 @@ public class SzParser { try { - var result = JsonSerializer.Deserialize(jsonString, _jsonOptions); - return result; + return JsonConvert.DeserializeObject(jsonString, _jsonSettings); } catch (Exception e) { @@ -39,9 +41,7 @@ public class SzParser { try { - var templateType = template.GetType(); - var jsonString = JsonSerializer.Serialize(template, templateType, _jsonOptions); - return jsonString; + return JsonConvert.SerializeObject(template, _jsonSettings); } catch (Exception e) { @@ -53,8 +53,7 @@ public class SzParser { try { - var result = JsonSerializer.Deserialize(jsonString, _jsonOptions); - return result; + return JsonConvert.DeserializeObject(jsonString, _jsonSettings); } catch (Exception e) { @@ -62,5 +61,4 @@ public class SzParser return default; } } -} - +} \ No newline at end of file