namespace ADOFAIRenderer.Data; /// /// Base class for integer input validation limits. /// Multiple limits can be composed on a single input field — all are checked in order. /// internal abstract class IntegerLimit { /// /// Validates the given integer value against this limit. /// /// The parsed integer 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(int value, out string errorMessage); } /// /// Requires the integer value to be strictly positive (> 0). /// internal class PositiveOnlyIntegerLimit : IntegerLimit { public override bool Validate(int value, out string errorMessage) { if (value > 0) { errorMessage = null!; return true; } errorMessage = "Value must be a positive integer greater than 0."; return false; } } /// /// Requires the integer value to be within an inclusive [Min, Max] range. /// Either bound can be null to represent an unbounded side. /// internal class RangeIntegerLimit : IntegerLimit { // ReSharper disable MemberCanBePrivate.Global public int? Min { get; } public int? 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 RangeIntegerLimit(int? min, int? max) { Min = min; Max = max; } public override bool Validate(int value, out string errorMessage) { if (value < Min) { errorMessage = Max.HasValue ? $"Value must be an integer between {Min.Value} and {Max.Value}." : $"Value must be an integer greater than or equal to {Min.Value}."; return false; } if (value > Max) { errorMessage = Min.HasValue ? $"Value must be an integer between {Min.Value} and {Max.Value}." : $"Value must be an integer less than or equal to {Max.Value}."; return false; } errorMessage = null!; return true; } }