namespace ADOFAIRenderer.Data; /// /// Base class for double input validation limits. /// Multiple limits can be composed on a single input field — all are checked in order. /// internal abstract class DoubleLimit { /// /// Validates the given double value against this limit. /// /// The parsed double value to validate. /// /// When validation fails, set to a human-readable error message. /// When validation succeeds, set to null. /// /// true if the value satisfies this limit; false otherwise. public abstract bool Validate(double value, out string errorMessage); } /// /// Requires the double value to be strictly positive (> 0). /// internal class PositiveOnlyDoubleLimit : DoubleLimit { public override bool Validate(double value, out string errorMessage) { if (value > 0) { errorMessage = null!; return true; } errorMessage = "Value must be a positive number greater than 0."; return false; } } /// /// Requires the double value to be within an inclusive [Min, Max] range. /// Either bound can be null to represent an unbounded side. /// internal class RangeDoubleLimit : DoubleLimit { // ReSharper disable MemberCanBePrivate.Global public double? Min { get; } public double? Max { get; } // ReSharper restore MemberCanBePrivate.Global /// Inclusive lower bound, or null for no lower bound. /// Inclusive upper bound, or null for no upper bound. public RangeDoubleLimit(double? min, double? max) { Min = min; Max = max; } public override bool Validate(double value, out string errorMessage) { if (value < Min) { errorMessage = Max.HasValue ? $"Value must be a number between {Min.Value} and {Max.Value}." : $"Value must be a number greater than or equal to {Min.Value}."; return false; } if (value > Max) { errorMessage = Min.HasValue ? $"Value must be a number between {Min.Value} and {Max.Value}." : $"Value must be a number less than or equal to {Max.Value}."; return false; } errorMessage = null!; return true; } }