diff --git a/src/Libs/Validator.php b/src/Libs/Validator.php index 8b4afd8..e69a5f3 100644 --- a/src/Libs/Validator.php +++ b/src/Libs/Validator.php @@ -228,6 +228,117 @@ class Validator return filter_var($subject, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) !== null; } + /** + * Checks if the value is a string. + * + * Note this is the strict type check: a PHP integer (e.g. 42) or an array + * fails, while any string - including a numeric string like "42" - passes. + * + * @param mixed $subject The value to check. + * + * @return bool + */ + public static function string(mixed $subject): bool + { + return is_string($subject); + } + + /** + * Checks if the value is an array. + * + * @param mixed $subject The value to check. + * + * @return bool + */ + public static function array(mixed $subject): bool + { + return is_array($subject); + } + + /** + * Measures a value for the size-based rules (min/max/between/size). + * + * A numeric value is measured by its number, a plain string by its + * character length, and an array by its element count. This single helper + * keeps the size semantics consistent and is where the file case (kilobytes) + * is added later. + * + * @param mixed $subject The value to measure. + * + * @return float + */ + private static function measure(mixed $subject): float + { + if (is_numeric($subject)) { + return (float) $subject; + } + + if (is_string($subject)) { + return (float) (function_exists('mb_strlen') ? mb_strlen($subject) : strlen($subject)); + } + + if (is_array($subject)) { + return (float) count($subject); + } + + return 0.0; + } + + /** + * Checks if the measured value is greater than or equal to a minimum. + * + * @param mixed $subject The value to check. + * @param mixed $min The minimum length, number or count. + * + * @return bool + */ + public static function min(mixed $subject, mixed $min): bool + { + return static::measure($subject) >= (float) $min; + } + + /** + * Checks if the measured value is less than or equal to a maximum. + * + * @param mixed $subject The value to check. + * @param mixed $max The maximum length, number or count. + * + * @return bool + */ + public static function max(mixed $subject, mixed $max): bool + { + return static::measure($subject) <= (float) $max; + } + + /** + * Checks if the measured value is within an inclusive range. + * + * @param mixed $subject The value to check. + * @param mixed $min The lower bound. + * @param mixed $max The upper bound. + * + * @return bool + */ + public static function between(mixed $subject, mixed $min, mixed $max): bool + { + $size = static::measure($subject); + + return $size >= (float) $min && $size <= (float) $max; + } + + /** + * Checks if the measured value is exactly a given size. + * + * @param mixed $subject The value to check. + * @param mixed $size The expected length, number or count. + * + * @return bool + */ + public static function size(mixed $subject, mixed $size): bool + { + return static::measure($subject) === (float) $size; + } + /** * Checks if the value is a valid email address. *