Initial commit
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
using RobotNet10.CustomConfiguration.Models;
|
||||
using System.Globalization;
|
||||
|
||||
namespace RobotNet10.CustomConfiguration.Validators;
|
||||
|
||||
/// <summary>
|
||||
/// Validator cho config files và variables
|
||||
/// </summary>
|
||||
public static class ConfigValidator
|
||||
{
|
||||
/// <summary>
|
||||
/// Validate một config file
|
||||
/// </summary>
|
||||
public static ValidationResult ValidateConfig(ConfigFile config)
|
||||
{
|
||||
var errors = new List<string>();
|
||||
|
||||
// Validate ConfigType
|
||||
if (string.IsNullOrWhiteSpace(config.ConfigType))
|
||||
{
|
||||
errors.Add("ConfigType cannot be empty");
|
||||
}
|
||||
|
||||
// Validate Variables
|
||||
if (config.Variables != null && config.Variables.Count > 0)
|
||||
{
|
||||
foreach (var variable in config.Variables)
|
||||
{
|
||||
var variableErrors = ValidateVariable(variable);
|
||||
errors.AddRange(variableErrors);
|
||||
}
|
||||
}
|
||||
|
||||
return new ValidationResult
|
||||
{
|
||||
IsValid = errors.Count == 0,
|
||||
Errors = errors
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate một variable
|
||||
/// </summary>
|
||||
public static List<string> ValidateVariable(ConfigVariable variable)
|
||||
{
|
||||
var errors = new List<string>();
|
||||
|
||||
// Validate Name
|
||||
if (string.IsNullOrWhiteSpace(variable.Name))
|
||||
{
|
||||
errors.Add("Variable name cannot be empty");
|
||||
}
|
||||
|
||||
// Validate Type
|
||||
if (!Enum.IsDefined(variable.Type))
|
||||
{
|
||||
errors.Add($"Invalid variable type: {variable.Type}");
|
||||
}
|
||||
|
||||
// Validate Value theo Type
|
||||
if (variable.Value == null)
|
||||
{
|
||||
errors.Add($"Variable '{variable.Name}' value cannot be null");
|
||||
}
|
||||
else
|
||||
{
|
||||
var valueErrors = ValidateValueByType(variable.Name, variable.Type, variable.Value, variable.Min, variable.Max, variable);
|
||||
errors.AddRange(valueErrors);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate value theo type và Min/Max constraints
|
||||
/// </summary>
|
||||
private static List<string> ValidateValueByType(string variableName, ConfigVariableType type, object value, double? min, double? max, ConfigVariable? variable = null)
|
||||
{
|
||||
var errors = new List<string>();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ConfigVariableType.Int:
|
||||
// Try parse
|
||||
if (int.TryParse(value.ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedInt))
|
||||
{
|
||||
if (min.HasValue && parsedInt < min.Value)
|
||||
errors.Add($"Variable '{variableName}' value {parsedInt} is less than Min {min.Value}");
|
||||
if (max.HasValue && parsedInt > max.Value)
|
||||
errors.Add($"Variable '{variableName}' value {parsedInt} is greater than Max {max.Value}");
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add($"Variable '{variableName}' must be an integer");
|
||||
}
|
||||
break;
|
||||
|
||||
case ConfigVariableType.Double:
|
||||
// Try parse
|
||||
if (double.TryParse(value.ToString(), NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var parsedDouble))
|
||||
{
|
||||
if (min.HasValue && parsedDouble < min.Value)
|
||||
errors.Add($"Variable '{variableName}' value {parsedDouble} is less than Min {min.Value}");
|
||||
if (max.HasValue && parsedDouble > max.Value)
|
||||
errors.Add($"Variable '{variableName}' value {parsedDouble} is greater than Max {max.Value}");
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add($"Variable '{variableName}' must be a double");
|
||||
}
|
||||
break;
|
||||
|
||||
case ConfigVariableType.Bool:
|
||||
if (!bool.TryParse(value.ToString(), out _))
|
||||
{
|
||||
errors.Add($"Variable '{variableName}' must be a boolean");
|
||||
}
|
||||
break;
|
||||
|
||||
case ConfigVariableType.Object:
|
||||
// Object có thể là Dictionary<string, object> hoặc JsonElement
|
||||
if (value is not Dictionary<string, object> &&
|
||||
value is not System.Text.Json.JsonElement)
|
||||
{
|
||||
// Try parse as JSON object
|
||||
try
|
||||
{
|
||||
var jsonString = value.ToString();
|
||||
if (jsonString != null)
|
||||
{
|
||||
using var doc = System.Text.Json.JsonDocument.Parse(jsonString);
|
||||
if (doc.RootElement.ValueKind != System.Text.Json.JsonValueKind.Object)
|
||||
{
|
||||
errors.Add($"Variable '{variableName}' must be a JSON object");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Text.Json.JsonException)
|
||||
{
|
||||
errors.Add($"Variable '{variableName}' must be a valid JSON object");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ConfigVariableType.Array:
|
||||
// Array có thể là List<object> hoặc JsonElement
|
||||
if (value is not List<object> &&
|
||||
value is not System.Text.Json.JsonElement)
|
||||
{
|
||||
// Try parse as JSON array
|
||||
try
|
||||
{
|
||||
var jsonString = value.ToString();
|
||||
if (jsonString != null)
|
||||
{
|
||||
using var doc = System.Text.Json.JsonDocument.Parse(jsonString);
|
||||
if (doc.RootElement.ValueKind != System.Text.Json.JsonValueKind.Array)
|
||||
{
|
||||
errors.Add($"Variable '{variableName}' must be a JSON array");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Text.Json.JsonException)
|
||||
{
|
||||
errors.Add($"Variable '{variableName}' must be a valid JSON array");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ConfigVariableType.Enum:
|
||||
if (variable == null || variable.EnumValues == null || variable.EnumValues.Count == 0)
|
||||
{
|
||||
errors.Add($"Variable '{variableName}' of type Enum must have EnumValues defined");
|
||||
}
|
||||
else
|
||||
{
|
||||
var valueStr = value?.ToString();
|
||||
if (string.IsNullOrEmpty(valueStr) || !variable.EnumValues.Contains(valueStr))
|
||||
{
|
||||
errors.Add($"Variable '{variableName}' value '{valueStr}' is not in allowed enum values: {string.Join(", ", variable.EnumValues)}");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Kết quả validation
|
||||
/// </summary>
|
||||
public class ValidationResult
|
||||
{
|
||||
public bool IsValid { get; set; }
|
||||
public List<string> Errors { get; set; } = [];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user