diff --git a/SzCli/Logger.cs b/SzCli/Logger.cs index 0719f40..5090ff2 100644 --- a/SzCli/Logger.cs +++ b/SzCli/Logger.cs @@ -5,21 +5,10 @@ namespace SzCli; public class Logger : ISzLogger { - private DefaultLocalFileManager _fileManager; public bool LogToFile { get; set; } = true; public string LogFilePath { get; set; } public int LogFileMaxLines { get; set; } = 100; - - public Logger(DefaultLocalFileManager fm) - { - _fileManager = fm; - LogFilePath = Path.Combine(_fileManager.DataPath, "log.txt"); - AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) => - { - LogError($"[EXCEPTION] {eventArgs.Exception}"); - }; - } - + public void Log(string text) { Console.WriteLine($"{DateTime.UtcNow} : [SZ LOG] {text}"); @@ -41,6 +30,16 @@ public class Logger : ISzLogger private void AppendLogFile(string text) { // TODO: Make sure log file adheres to LogFileMaxLines + + if (!File.Exists(LogFilePath)) + { + LogFilePath = Path.Combine(SZ.LocalFileManager.DataPath, "log.txt"); + AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) => + { + LogError($"[EXCEPTION] {eventArgs.Exception}"); + }; + } + File.AppendAllText(LogFilePath, text + "\n"); } } \ No newline at end of file diff --git a/SzCli/Program.cs b/SzCli/Program.cs index e5d796a..78cbf43 100644 --- a/SzCli/Program.cs +++ b/SzCli/Program.cs @@ -7,253 +7,12 @@ namespace SzCli; public class Program { - private static readonly DefaultLocalFileManager _fileManager = new(); - private static readonly Logger _logger = new(_fileManager); - private static readonly DefaultDatabaseHandler _dbHandler = new(); + private static readonly DefaultLocalFileManager FileManager = new(); + private static readonly Logger Logger = new(); + private static readonly DefaultDatabaseHandler DbHandler = new(); public static void Main(string[] args) { - SZ.Init(_fileManager, _logger, _dbHandler); - - bool shouldClose = false; - - while (!shouldClose) - { - Console.WriteLine(" -- SZ CLI MAIN MENU -- "); - Console.WriteLine("0: Exit"); - Console.WriteLine("1: Create Template"); - Console.WriteLine("2: Create Dataset"); - Console.WriteLine("3: Evaluate Dataset"); - Console.WriteLine("4: Delete Template"); - Console.WriteLine("5: Delete Dataset"); - // Console.WriteLine("6: Fetch Template"); - // Console.WriteLine("7: Fetch Dataset"); - - Console.Write("> "); - var userInput = Console.ReadLine(); - if (!int.TryParse(userInput, out var result)) - { - Console.WriteLine($"Input was not a number, please try again.\n\n"); - continue; - } - - switch (result) - { - case 0: - shouldClose = true; - break; - case 1: - CreateTemplate(); - break; - case 2: - CreateDataset(); - break; - case 3: - EvaluateDataset(); - break; - case 4: - DeleteTemplate(); - break; - case 5: - DeleteDataset(); - break; - default: - Console.WriteLine("Invalid input, please try again"); - break; - } - } - - Console.WriteLine("\n\n"); - } - - private static void DeleteDataset() - { - Console.Write("Dataset ID: "); - var userInput = Console.ReadLine(); - if (string.IsNullOrEmpty(userInput)) - { - Console.WriteLine("Id was null"); - return; - } - SZ.SzDataHandler.DeleteDataset(userInput); - } - - private static void DeleteTemplate() - { - Console.Write("Template ID: "); - var userInput = Console.ReadLine(); - if (string.IsNullOrEmpty(userInput)) - { - Console.WriteLine("Id was null"); - return; - } - SZ.SzDataHandler.DeleteTemplate(userInput); - } - - private static void EvaluateDataset() - { - Console.Write("Dataset ID: "); - var userInput = Console.ReadLine(); - if (string.IsNullOrEmpty(userInput)) - { - Console.WriteLine("Id was null"); - return; - } - var dataset = SZ.SzDataHandler.LoadDataset(userInput); - if (dataset is null) - { - Console.WriteLine($"Dataset with ID {userInput} could not be loaded"); - return; - } - - var evalResult = SZ.SzEvaluator.EvaluateDataset(dataset); - } - - private static void CreateDataset() - { - Console.Write("Enter a name for the dataset: "); - var nameInput = Console.ReadLine(); - if (string.IsNullOrEmpty(nameInput)) - { - Console.WriteLine("Dataset name can't be blank"); - return; - } - - var id = nameInput.ToLower().Replace(" ", "-").Trim(); - - Console.Write("Enter template ID: "); - var templateIdInput = Console.ReadLine(); - if (string.IsNullOrEmpty(templateIdInput)) - { - Console.WriteLine("Template ID can't be blank"); - return; - } - - var template = SZ.SzDataHandler.LoadTemplate(templateIdInput); - if (template is null) - { - Console.WriteLine($"Could not load template with ID {templateIdInput}"); - return; - } - - - - - } - - private static void CreateTemplate() - { - Console.Write("Enter a name for the template: "); - var nameInput = Console.ReadLine(); - if (string.IsNullOrEmpty(nameInput)) - { - Console.WriteLine("Template name can't be blank"); - return; - } - - var id = nameInput.ToLower().Replace(" ", "-").Trim(); - - Console.Write("Enter a data type for the template: "); - var dataTypeInput = Console.ReadLine(); - if (string.IsNullOrEmpty(dataTypeInput)) - { - Console.WriteLine("Template Data Type can't be blank"); - return; - } - - Console.Write("Enter a description for the template: "); - var descInput = Console.ReadLine(); - - var fields = CreateTemplateFields(); - - var newTemplate = new SzDataObjectTemplate() - { - Name = nameInput, - Id = id, - DataObjectType = dataTypeInput, - Description = descInput ?? "", - }; - - foreach (var f in fields) - { - newTemplate.TemplateFields.Add(f.Id, f); - } - - SZ.SzDataHandler.SaveTemplate(newTemplate); - - } - - private static List CreateTemplateFields() - { - bool done = false; - int i = 0; - List list = []; - while (!done) - { - i++; - Console.Write($"Field {i} ID: "); - var idInput = Console.ReadLine(); - if (string.IsNullOrEmpty(idInput)) - { - Console.WriteLine("Field id can't be blank"); - i--; - continue; - } - - if (list.Any(f => f.Id == idInput)) - { - Console.WriteLine($"Field id '{idInput}' must be unique"); - i--; - continue; - } - - Console.WriteLine($"Field {idInput} type: "); - int enumIter = 0; - foreach (var enumType in Enum.GetValues()) - { - Console.WriteLine($"- {enumType}"); - enumIter++; - } - Console.Write("> "); - var typeInput = Console.ReadLine(); - if (!Enum.TryParse(typeInput, out var typeEnumResult)) - { - Console.WriteLine("Field type input was invalid"); - i--; - continue; - } - - // Console.Write("Is the field a list?: "); - // var isListInput = Console.ReadLine(); - // if (!bool.TryParse(isListInput, out var isListResult)) - // { - // Console.WriteLine("Field isList input was invalid"); - // i--; - // continue; - // } - - Console.Write("Add another field? "); - var contInput = Console.ReadLine(); - switch (contInput) - { - case "n": - case "N": - default: - done = true; - break; - case "y": - case "Y": - break; - } - - var newField = new SzTemplateField(){ - Id = idInput, - FieldType = typeEnumResult - }; - - list.Add(newField); - } - - return list; + SZ.Init(FileManager, Logger, DbHandler); } } diff --git a/SzCli/Test.cs b/SzCli/Test.cs index 316de64..4bf28ff 100644 --- a/SzCli/Test.cs +++ b/SzCli/Test.cs @@ -28,7 +28,7 @@ public static class Test dt.TemplateFields.Add(testTemplateField.Id, testTemplateField); - SZ.SzDataHandler.SaveTemplate(dt); + SZ.DataHandler.SaveTemplate(dt); var ds = new SzDataset() { @@ -56,7 +56,7 @@ public static class Test testDataObject.Fields.Add(testField.Id, testField); ds.DataObjects.Add(testDataObject.Id, testDataObject); - SZ.SzDataHandler.SaveDataset(ds); + SZ.DataHandler.SaveDataset(ds); } catch (Exception e) { diff --git a/SzCore/SZ.cs b/SzCore/SZ.cs index 4ffae83..40f86f2 100644 --- a/SzCore/SZ.cs +++ b/SzCore/SZ.cs @@ -10,9 +10,9 @@ public static class SZ public static bool IsInitalized { get; private set; } = false; - public static readonly SzParser SzParser = new(); - public static readonly SzDataHandler SzDataHandler = new(); - public static readonly SzEvaluator SzEvaluator = new(); + public static readonly SzParser Parser = new(); + public static readonly SzDataHandler DataHandler = new(); + public static readonly SzEvaluator Evaluator = new(); public static ISzFileManager LocalFileManager { @@ -44,14 +44,15 @@ public static class SZ } } - private static readonly Dictionary _services = []; - private static readonly List _protectedServices = []; + private static readonly Dictionary Services = []; + private static readonly List ProtectedServices = []; /// /// Initalizes the SZ singleton in SzCore /// /// An ISzFileManager instance. /// An ISzLogger instance. + /// An ISzDatabaseHandler instance /// /// Throws if SZ has already been initalized public static void Init(ISzFileManager fileManager, ISzLogger logger, ISzDatabaseHandler databaseHandler) { @@ -96,14 +97,14 @@ public static class SZ { CheckInitialization(); - var result = _services.TryAdd(instance.GetType(), instance); + var result = Services.TryAdd(instance.GetType(), instance); if (!result) return false; if (isProtected) { - if (_protectedServices.Contains(instance.GetType())) return false; + if (ProtectedServices.Contains(instance.GetType())) return false; - _protectedServices.Add(instance.GetType()); + ProtectedServices.Add(instance.GetType()); } return result; @@ -113,16 +114,16 @@ public static class SZ { CheckInitialization(); - if (!_services.ContainsKey(typeof(T))) return default; - return (T)_services[typeof(T)]; + if (!Services.ContainsKey(typeof(T))) return default; + return (T)Services[typeof(T)]; } public static bool RemoveService() { CheckInitialization(); - if (_protectedServices.Contains(typeof(T))) return false; - return _services.Remove(typeof(T)); + if (ProtectedServices.Contains(typeof(T))) return false; + return Services.Remove(typeof(T)); } private static void CheckInitialization() diff --git a/SzCore/SzDataHandler.cs b/SzCore/SzDataHandler.cs index e61a2fe..2a85178 100644 --- a/SzCore/SzDataHandler.cs +++ b/SzCore/SzDataHandler.cs @@ -10,7 +10,6 @@ public class SzDataHandler public SzDataHandler(){} - // The client should periodically call this to free memory, probably private void ClearCache() { _loadedDatasets.Clear(); @@ -18,39 +17,40 @@ public class SzDataHandler } #region Datasets - public bool SaveDataset(SzDataset dataset) + public SzResult SaveDataset(SzDataset dataset) { var datasetPath = Path.Combine(SZ.LocalFileManager.DatasetsPath, dataset.Id, "dataset.json"); try { - return SZ.LocalFileManager.SaveFile(datasetPath, SZ.SzParser.SerializeDatasetToJson(dataset)); + var success = SZ.LocalFileManager.SaveFile(datasetPath, SZ.Parser.SerializeDatasetToJson(dataset)); + return success ? SzResult.Success(true) : SzResult.Failure("Failed to write dataset file."); } catch (Exception e) { SZ.Logger.LogError("Error saving dataset: " + e.Message); - return false; + return SzResult.Failure(e.Message); } } - public bool DeleteDataset(string datasetId) + public SzResult DeleteDataset(string datasetId) { try { Directory.Delete(Path.Combine(SZ.LocalFileManager.DatasetsPath, datasetId), true); - return true; + return SzResult.Success(true); } catch (Exception e) { SZ.Logger.LogError($"Could not delete Dataset with id '{datasetId}': {e.Message}"); - return false; + return SzResult.Failure(e.Message); } } - public SzDataset? LoadDataset(string datasetId) + public SzResult LoadDataset(string datasetId) { if (_loadedDatasets.TryGetValue(datasetId, out SzDataset? value)) { - return value; + return SzResult.Success(value); } var datasetPath = Path.Combine(SZ.LocalFileManager.DataPath, "datasets", datasetId, "dataset.json"); @@ -59,61 +59,78 @@ public class SzDataHandler if (json is null) { SZ.Logger.LogWarning($"Could not load dataset with ID '{datasetId}'"); - return null; + return SzResult.Failure($"Could not find dataset file for ID '{datasetId}'"); } - var parsedDataset = SZ.SzParser.DeserializeDataset(json); + var parsedDataset = SZ.Parser.DeserializeDataset(json); if (parsedDataset is null) { SZ.Logger.LogWarning($"Could not load dataset with ID '{datasetId}'"); - return null; + return SzResult.Failure($"Failed to parse dataset JSON for ID '{datasetId}'"); } _loadedDatasets.Add(parsedDataset.Id, parsedDataset); - return parsedDataset; + return SzResult.Success(parsedDataset); } - public SzDataset CreateDataset() + public SzResult CreateDataset(string name, string templateId, string? id = null, Guid? templateUuid = null) { + if (string.IsNullOrEmpty(name)) + return SzResult.Failure("Dataset name cannot be empty."); + var templateResult = LoadTemplate(templateId); + if (!templateResult.IsSuccess || templateResult.Value is null) + return SzResult.Failure($"Template '{templateId}' not found."); + + var newDataset = new SzDataset() + { + Name = name, + Id = id ?? name.ToLower().Replace(" ", "-").Trim(), + DataObjectTemplateId = templateResult.Value.Id, + DataObjectTemplateUuid = templateUuid, + DataObjectType = templateResult.Value.DataObjectType, + Uuid = Guid.NewGuid() + }; + + return SzResult.Success(newDataset); } - #endregion #region Templates - public bool SaveTemplate(ISzTemplate template) + public SzResult SaveTemplate(ISzTemplate template) { var templatePath = Path.Combine(SZ.LocalFileManager.TemplatesPath, template.Id, "template.json"); try { - return SZ.LocalFileManager.SaveFile(templatePath, SZ.SzParser.SerializeTemplateToJson(template)); + var success = SZ.LocalFileManager.SaveFile(templatePath, SZ.Parser.SerializeTemplateToJson(template)); + return success ? SzResult.Success(true) : SzResult.Failure("Failed to write template file."); } catch (Exception e) { SZ.Logger.LogError("Error saving template: " + e.Message); - return false; + return SzResult.Failure(e.Message); } } - public bool DeleteTemplate(string templateId) + public SzResult DeleteTemplate(string templateId) { try { Directory.Delete(Path.Combine(SZ.LocalFileManager.TemplatesPath, templateId), true); - return true; + return SzResult.Success(true); } catch (Exception e) { SZ.Logger.LogError($"Could not delete Template with id '{templateId}': {e.Message}"); - return false; + return SzResult.Failure(e.Message); } } - public T? LoadTemplate(string templateId) where T : ISzTemplate + public SzResult LoadTemplate(string templateId) where T : ISzTemplate { - if (_loadedTemplates.TryGetValue(templateId, out ISzTemplate? existing)) + if (_loadedTemplates.TryGetValue(templateId, out ISzTemplate? cachedTemplate)) { - return (T)existing; + return SzResult.Success((T)cachedTemplate); } var templatePah = Path.Combine(SZ.LocalFileManager.TemplatesPath, templateId, "template.json"); @@ -121,63 +138,50 @@ public class SzDataHandler var json = SZ.LocalFileManager.LoadFile(templatePah); if (json is null) { - SZ.Logger.LogWarning($"Could not load tetmplate with ID '{templateId}'"); - return default; + SZ.Logger.LogWarning($"Could not load template with ID '{templateId}'"); + return SzResult.Failure($"Could not find template file for ID '{templateId}'"); } - var parsedTemplate = SZ.SzParser.DeserializeTemplate(json); + var parsedTemplate = SZ.Parser.DeserializeTemplate(json); if (parsedTemplate is null) { SZ.Logger.LogWarning($"Could not load template with ID '{templateId}'"); - return default; + return SzResult.Failure($"Failed to parse template JSON for ID '{templateId}'"); } _loadedTemplates.TryAdd(parsedTemplate.Id, parsedTemplate); - return parsedTemplate; + return SzResult.Success(parsedTemplate); } - public SzDataObjectTemplate? CreateDataObjectTemplate(string name, string dataObjectType, string? id = null, string? description = null, List? fields = null) + public SzResult CreateDataObjectTemplate(string name, string dataObjectType, string? id = null, string? description = null, List? fields = null) { - if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(dataObjectType)) return null; - - string newId; - if (!string.IsNullOrEmpty(id)) - { - newId = id; - } - else - { - newId = name.ToLower().Replace(" ", "-").Trim(); - } + if (string.IsNullOrEmpty(name)) return SzResult.Failure("Name cannot be empty."); + if (string.IsNullOrEmpty(dataObjectType)) return SzResult.Failure("DataObjectType cannot be empty."); var newTemplate = new SzDataObjectTemplate() { Name = name, - Id = newId, + Id = id ?? name.ToLower().Replace(" ", "-").Trim(), DataObjectType = dataObjectType, Uuid = Guid.NewGuid(), Description = description ?? "" }; - if (fields is not null) + if (fields is null) return SzResult.Success(newTemplate); + foreach (var field in fields) { - foreach (var field in fields) - { - newTemplate.TemplateFields.Add(field.Id, field); - } + newTemplate.TemplateFields.Add(field.Id, field); } - return newTemplate; - + return SzResult.Success(newTemplate); } #endregion #region Other - - public SzTemplateField? CreateTemplateField(string id, SzFieldType fieldType, bool isList = false, string? defaultValue = null, bool isSpecialType = false, string? specialTypeValue = null) + public SzResult CreateTemplateField(string id, SzFieldType fieldType, bool isList = false, string? defaultValue = null, bool isSpecialType = false, string? specialTypeValue = null) { - if (string.IsNullOrEmpty(id)) return null; + if (string.IsNullOrEmpty(id)) return SzResult.Failure("ID cannot be empty."); var newField = new SzTemplateField() { @@ -189,13 +193,21 @@ public class SzDataHandler SpecialTypeValue = specialTypeValue ?? "" }; - return newField; + return SzResult.Success(newField); } + public SzResult> CreateFields(ISzTemplate template) + { + return SzResult>.Failure("Not implemented"); + } + + public SzResult CreateDataObject() + { + return SzResult.Failure("Not implemented"); + } #endregion #region Tests - // Only use these two methods for test purposes, we probably don't want to load all datasets and templates to memory in production private void LoadAllDatasets() { _loadedDatasets.Clear(); @@ -212,7 +224,7 @@ public class SzDataHandler var datasetJson = SZ.LocalFileManager.LoadFile(datasetFilePath); if (datasetJson == null) continue; - var parsedDataset = SZ.SzParser.DeserializeDataset(datasetJson); + var parsedDataset = SZ.Parser.DeserializeDataset(datasetJson); if (parsedDataset == null) { SZ.Logger.LogWarning($"Parse error: Could not parse file {datasetFilePath} as an SzDataset"); @@ -239,7 +251,7 @@ public class SzDataHandler var templateJson = SZ.LocalFileManager.LoadFile(templateFilePath); if (templateJson == null) continue; - var parsedTemplate = SZ.SzParser.DeserializeTemplate(templateJson); + var parsedTemplate = SZ.Parser.DeserializeTemplate(templateJson); if (parsedTemplate == null) { SZ.Logger.LogWarning($"Parse error: Could not parse file {templateFilePath} as an ISzTemplate"); diff --git a/SzCore/SzEvaluator.cs b/SzCore/SzEvaluator.cs index 290f878..b18cd69 100644 --- a/SzCore/SzEvaluator.cs +++ b/SzCore/SzEvaluator.cs @@ -7,29 +7,25 @@ namespace SzCore; public class SzEvaluator { - public SzOperationResult EvaluateDataset(SzDataset dataset) + public SzResult EvaluateDataset(SzDataset dataset) { - if (dataset is null) return new SzOperationResult(false, "Dataset cannot be null"); - var errors = new StringBuilder(); - var template = SZ.SzDataHandler.LoadTemplate(dataset.DataObjectTemplateId); - if (template is null) return new SzOperationResult(false, $"Template with id {dataset.DataObjectTemplateId} for Dataset ID {dataset.Id} could not be loaded"); + var template = SZ.DataHandler.LoadTemplate(dataset.DataObjectTemplateId); + if (!template.IsSuccess || template.Value is null) return SzResult.Failure($"Template with id {dataset.DataObjectTemplateId} for Dataset ID {dataset.Id} could not be loaded"); foreach (var dataObject in dataset.DataObjects.Values) { - var evalResult = EvaluateDataObject(dataObject, template); - if (!evalResult.Pass) errors.Append(evalResult.Errors); + var evalResult = EvaluateDataObject(dataObject, template.Value); + if (!evalResult.IsSuccess) errors.Append(evalResult.Error); } var errString = errors.ToString(); - return new SzOperationResult(string.IsNullOrEmpty(errString), errString); + return string.IsNullOrEmpty(errString) ? SzResult.Success(true) : SzResult.Failure(errString); } - public SzOperationResult EvaluateDataObject(SzDataObject dataObject, SzDataObjectTemplate template) + public SzResult EvaluateDataObject(SzDataObject dataObject, SzDataObjectTemplate template) { - if (dataObject is null || template is null) return new SzOperationResult(false, "dataObject or template is null"); - var errors = new StringBuilder(); foreach (var (key, templateField) in template.TemplateFields) @@ -41,10 +37,10 @@ public class SzEvaluator } var templateMatchResult = DoesFieldMatchTemplateField(matchingField, templateField); - if (!templateMatchResult.Pass) errors.Append(templateMatchResult.Errors); + if (!templateMatchResult.IsSuccess) errors.Append(templateMatchResult.Error); var evalResult = EvaluateFieldValue(matchingField); - if (!evalResult.Pass) errors.Append(evalResult.Errors); + if (!evalResult.IsSuccess) errors.Append(evalResult.Error); } foreach (var objectFieldKey in dataObject.Fields.Keys) @@ -56,10 +52,10 @@ public class SzEvaluator } var errString = errors.ToString().Trim(); - return new SzOperationResult(string.IsNullOrEmpty(errString), string.IsNullOrEmpty(errString) ? "" : errString); + return string.IsNullOrEmpty(errString) ? SzResult.Success(true) : SzResult.Failure(errString); } - public SzOperationResult DoesFieldMatchTemplateField(SzField field, SzTemplateField templateField) + public SzResult DoesFieldMatchTemplateField(SzField field, SzTemplateField templateField) { var errors = new StringBuilder(); @@ -68,13 +64,13 @@ public class SzEvaluator if (field.IsList != templateField.IsList) errors.AppendLine($"Field '{field.Id}' IsList mismatch: Expected {templateField.IsList}"); var errString = errors.ToString().Trim(); - return new SzOperationResult(string.IsNullOrEmpty(errString), errString); + return string.IsNullOrEmpty(errString) ? SzResult.Success(true) : SzResult.Failure(errString); } - public SzOperationResult EvaluateFieldValue(SzField field) + public SzResult EvaluateFieldValue(SzField field) { if (string.IsNullOrWhiteSpace(field.Value)) - return new SzOperationResult(true, ""); + return SzResult.Success(true); var errors = new StringBuilder(); @@ -111,6 +107,6 @@ public class SzEvaluator } var errString = errors.ToString().Trim(); - return new SzOperationResult(string.IsNullOrEmpty(errString), errString); + return string.IsNullOrEmpty(errString) ? SzResult.Success(true) : SzResult.Failure(errString); } -} +} \ No newline at end of file diff --git a/SzCore/SzException.cs b/SzCore/SzException.cs new file mode 100644 index 0000000..a69220b --- /dev/null +++ b/SzCore/SzException.cs @@ -0,0 +1,8 @@ +namespace SzCore; + +public class SzException : Exception +{ + public SzException() {} + public SzException(string message) : base (message) {} + public SzException(string message, Exception inner) : base(message, inner) {} +} \ No newline at end of file diff --git a/SzCore/SzOperationResult.cs b/SzCore/SzOperationResult.cs deleted file mode 100644 index 1ec10a2..0000000 --- a/SzCore/SzOperationResult.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace SzCore; - -public class SzOperationResult(bool pass, string errors = "None") -{ - public bool Pass = pass; - public string Errors = errors; -} diff --git a/SzCore/SzResult.cs b/SzCore/SzResult.cs new file mode 100644 index 0000000..e4f94ad --- /dev/null +++ b/SzCore/SzResult.cs @@ -0,0 +1,14 @@ +namespace SzCore; + +public class SzResult +{ + public bool IsSuccess { get; } + public T? Value { get; } + public string? Error { get; } + + protected SzResult(T? value, bool success, string? error) + => (Value, IsSuccess, Error) = (value, success, error); + + public static SzResult Success(T value) => new(value, true, null); + public static SzResult Failure(string error) => new(default, false, error); +} \ No newline at end of file