From 9db0aac02771323366b79f48f9b90f32a47e27cc Mon Sep 17 00:00:00 2001 From: Rodolfo Berrios <20590102+rodber@users.noreply.github.com> Date: Tue, 9 Jan 2024 12:04:30 -0300 Subject: [PATCH] parameter package --- library/parameter.md | 374 --------- packages/naming.php | 1 + packages/parameter.md | 958 ++++++++++++++++++++++ src/packages/parameter/parameter-logo.svg | 8 + 4 files changed, 967 insertions(+), 374 deletions(-) delete mode 100644 library/parameter.md create mode 100644 packages/parameter.md create mode 100644 src/packages/parameter/parameter-logo.svg diff --git a/library/parameter.md b/library/parameter.md deleted file mode 100644 index f90d58e..0000000 --- a/library/parameter.md +++ /dev/null @@ -1,374 +0,0 @@ -# Parameter - -Namespace `Chevere\Parameter` - -The Parameter component is in charge of providing an user-land typed layer abstraction around parameter-argument. Intended to be used in I/O validation systems, this component provide dynamic parameter-argument type matching relying on the [Type](type.md) component. - -To summarize, Parameter enables to validate any type of arguments for any kind of data-structure. - -## Array Parameter - -Use function `arrayp` to create an array parameter for required array keys. - -```php -use function Chevere\Parameter\arrayp; - -// Empty array -$parameter = arrayp(); -// With required 'a' key -$parameter = arrayp(a: string()); -``` - -### With parameters - -Use method `withRequired` to define **required** parameters to an existing object implementing `ArrayParameterInterface`. - -```php -$parameter = $parameter - ->withRequired( - username: string(), - email: string() - ); -``` - -Use method `withOptional` to define **optional** parameters to an existing object implementing `ArrayParameterInterface`. - -```php -$parameter = $parameter - ->withOptional(email: string()); -``` - -👉 **Note:** Optional parameters will be validated only if a matching key is provided. - -### Array String - -Use function `arrayString` to create an array parameter for required array keys. It only supports string parameters. - -```php -use function Chevere\Parameter\arrayString; -use function Chevere\Parameter\string; - -$parameter = arrayString( - test: string(), -); -``` - -### Array assertion - -Use function `assertArray` to validate an array parameter against an array argument. It returns the *typed* array. - -```php -use function Chevere\Parameter\assertArray; - -$parameter = arrayp( - a: string(), - b: integer(), -); -$argument = [ - 'a' => 'Hello world', - 'b' => 123 -]; -$assert = assertArray($parameter, $argument); -// $assert same as $argument -``` - -If you define a **default value** for any parameter the system will fill in that value when not provided. - -```php -use function Chevere\Parameter\assertArray; - -$parameter = arrayp( - foo: integer(default: 100), -); -$argument = []; -$assert = assertArray($parameter, $argument); -// $assert = ['foo' => 100]; -``` - -## Boolean Parameter - -Use function `boolean` to create a parameter implementing `BooleanParameterInterface`. This function can define `description` and a `default` value. - -```php -use function Chevere\Parameter\boolean; - -$parameter = boolean(); -``` - -### Boolean assertion - -Use function `assertBoolean` to validate a boolean parameter against a boolean argument. - -```php -use function Chevere\Parameter\assertBoolean; - -$parameter = boolean(); -$argument = true; -assertBoolean($parameter, $argument); -``` -˝ -## Float Parameter - -Use function `float` to create a parameter implementing `FloatParameterInterface`. This function can define `description`, `default` value, `minimum` value, `maximum` value and a float list of `accept` values. - -```php -use function Chevere\Parameter\float; - -// Any float -$float = float(); -// Limited range float -$float = float( - minimum: 0, - maximum: 100 -); -// Exact float match -$float = float( - accept: [1, 2, 3] -); -``` - -### Float assertion - -Use function `assertFloat` to validate a float parameter against a float argument. - -```php -use function Chevere\Parameter\assertFloat; - -$parameter = float( - minimum: 0.0, - maximum: 10.0 -); -$argument = 5.5; -assertFloat($parameter, $argument); -``` - -## Generic Parameter - -Use function `generic` to create a parameter implementing `GenericParameterInterface`. This function can define a parameter value `V` and parameter key `K`. - -💡 A generic parameter is used to match a variable collection of `n-items`. - -```php -use function Chevere\Parameter\generic; - -// For a collection of integer keys -// and string values -$parameter = generic( - string(), -); -``` - -### Generic assertion - -Use function `assertGeneric` to validate a generic parameter against a generic argument. - -```php -use function Chevere\Parameter\assertGeneric; - -$parameter = generic( - K: integer(minimum: 0), - V: arrayp( - id: string(), - name: string(), - ), -); -$argument = [ - 0 => [ - 'id' => '123e4567', - 'name' => 'Rodolfo' - ], - 1 => [ - 'id' => '123e4568', - 'name' => 'Alejandro' - ], - // ... -]; -assertGeneric($parameter, $argument); -``` - -## Integer Parameter - -Use function `integer` to create a parameter implementing `IntegerParameterInterface`. This function can define `description`, `default` value, `minimum` value, `maximum` value and a integer list of `accept` values. - -```php -use function Chevere\Parameter\integer; - -// Any integer -$integer = integer(); -// Limited range integer -$integer = integer( - minimum: 0, - maximum: 100 -); -// Exact integer match -$integer = integer( - accept: [1, 2, 3] -); -``` - -### Integer assertion - -Use function `assertInteger` to validate an integer parameter against an integer argument. - -```php -use function Chevere\Parameter\assertInteger; - -$parameter = integer( - minimum: 0.0, - maximum: 10.0 -); -$argument = 5.5; -assertInteger($parameter, $argument); -``` - -## Null Parameter - -Use function `null` to create a parameter implementing `NullParameterInterface`. This function can define `description`. - -```php -use function Chevere\Parameter\null; - -$null = null(); -``` - -### Null assertion - -Use function `assertNull` to validate a null parameter against a null argument. - -```php -use function Chevere\Parameter\assertNull; - -$parameter = null(); -$argument = null; -assertNull($parameter, $argument); -``` - -## Object Parameter - -Use function `object` to create a parameter implementing `ObjectParameterInterface`. This function can define a `clasName` and a `description`. - -```php -use function Chevere\Parameter\object; - -$object = object(stdClass::class); -``` - -### Object assertion - -Use function `assertObject` to validate an object parameter against an object argument. - -```php -use function Chevere\Parameter\assertObject; - -$parameter = object(); -$argument = new stdClass(); -assertObject($parameter, $argument); -``` - -## String Parameter - -Use function `string` to create a parameter implementing `StringParameterInterface`. This function can define a `regex` for string matching, a `description` and a `default` value. - -```php -use function Chevere\Parameter\string; - -// Any string -$parameter = string(); -// A string matching id-123 -$string = string('/^id-[\d]+$/'); -``` - -### Enum string - -Use function `enump` to create an enum string parameter. This function takes strings used for the enumeration. - -```php -use function Chevere\Parameter\enum; - -// A string matching on OR off -$parameter = enum('on', 'off'); -``` - -### Date string - -Use function `date` to create a date string parameter for `YYYY-MM-DD`. This function can define `description` and a `default` value. - -```php -use function Chevere\Parameter\date; - -// A YYYY-MM-DD string -$parameter = date(); -``` - -### Time string - -Use function `time` to create a time string parameter for `hh:mm:ss`. This function can define `description` and a `default` value. - -```php -use function Chevere\Parameter\time; - -// A hh:mm:ss string -$parameter = time(); -``` - -### Datetime string - -Use function `datetime` to create a datetime string parameter for `YYYY-MM-DD hh:mm:ss`. This function can define `description` and a `default` value. - -```php -use function Chevere\Parameter\datetime; - -// A YYYY-MM-DD hh:mm:ss -$parameter = datetime(); -``` - -### String assertion - -Use function `assertString` to validate a string parameter against a string argument. - -```php -use function Chevere\Parameter\assertString; - -$parameter = string('/^a|b|c$/'); -$argument = 'a'; -assertString($parameter, $argument); -``` - -## Union Parameter - -Use function `union` to create a parameter implementing `UnionParameterInterface`. An union parameter works similar to PHP's union type as it enables to validate an argument against multiple types. - -```php -use function Chevere\Parameter\union; - -// Any string or null -$union = union(string(), null()); -// Any digit string or any integer -$union = union( - string('/^\d+$/'), - integer() -); -``` - -### Union assertion - -Use function `assertUnion` to validate an union parameter against a mixed argument. - -```php -use function Chevere\Parameter\assertUnion; - -$union = union(string(), integer()); -assertUnion($parameter, 'abc'); -assertUnion($parameter, 0); -``` - -## Argument assertion - -Use function `assertArgument` to validate a parameter against an argument of any type. Useful when there's no certainty on the argument type. - -```php -use function Chevere\Parameter\assertArgument; - -$parameter = string(); -assertArgument($parameter, $argument); -``` diff --git a/packages/naming.php b/packages/naming.php index 21de436..091cc93 100644 --- a/packages/naming.php +++ b/packages/naming.php @@ -13,5 +13,6 @@ 'regex.md' => 'Regex', 'message.md' => 'Message', 'writer.md' => 'Writer', + 'parameter.md' => 'Parameter', 'http.md' => 'Http', ]; diff --git a/packages/parameter.md b/packages/parameter.md new file mode 100644 index 0000000..75b0b9a --- /dev/null +++ b/packages/parameter.md @@ -0,0 +1,958 @@ +# Parameter + +![Parameter](../src/packages/parameter/parameter-logo.svg) + +## Summary + +Parameter is a library around parameter-argument which provides additional functionality with validation rules and schema introspection. + +## What it does? + +Parameter enables to spawn dynamic parameters of any type with extra rules. + +For example, an integer of minimum value 10: + +```php +use function Chevere\Parameter\int; + +$int = int(min: 10); +$int($var); // exception if $var < 10 +``` + +In function or method parameters you can use attributes to define validation rules for parameters and return value: + +```php +use Chevere\Parameter\Attributes\FloatAttr; +use Chevere\Parameter\Attributes\IntAttr; +use Chevere\Parameter\Attributes\ReturnAttr; +use function Chevere\Parameter\returnAttr; +use function Chevere\Parameter\valid; + +#[ReturnAttr( + new FloatAttr(min: 0, max: 2400) +)] +function wageWeekWA( + #[IntAttr(min: 1628)] + int $cents, + #[FloatAttr(min: 0, max: 40)] + float $hours +) { + valid(); // valid $cents, $hours + $wage = $cents*$hours/100; + return returnAttr()($wage); // valid $wage +} +``` + +Validation can be triggered inline (examples above in function body) or delegated to a caller wrapper. Parameter provides helpers to access these rules to ease wiring process. + +Rules defined by each parameter provide a human-readable schema which allows to expose the validation criteria. + +## How to use + +Parameter provides an API which can be used to create parameters using functions and/or attributes. Parameter objects can be used directly in the logic while attributes requires a read step. + +### Inline usage + +Use [inline validation](#inline-validation) to go from this: + +```php +if($var > 10 || $var < 1) { + throw new InvalidArgumentException(); +} +``` + +To this: + +```php +use function \Chevere\Parameter\int; + +int(min: 1, max: 10)($var); +``` + +### Attribute-based usage + +Use [attribute delegated validation](#attribute-delegated-validation) with the `validated()` function to go from this: + +```php +function myFunction(int $var): string +{ + if($var > 10 || $var < 1) { + throw new InvalidArgumentException(); + } + $return = 'done ok'; + return preg_match('/ok$/', $return) + ? $return + : throw new InvalidArgumentException(); +} +$result = myFunction($var); +``` + +To this: + +```php +use Chevere\Parameter\Attributes\IntAttr; +use Chevere\Parameter\Attributes\ReturnAttr; +use Chevere\Parameter\Attributes\StringAttr; +use function Chevere\Parameter\validated; + +#[ReturnAttr( + new StringAttr('/ok$/') +)] +function myFunction( + #[IntAttr(min: 1, max: 10)] + int $var +): string +{ + return 'done ok'; +} +$result = validated('myFunction', $var); +``` + +Use `reflectionToParameters` and `reflectionToReturn` functions for manual validation for arguments and return value: + +```php +use ReflectionFunction; +use function Chevere\Parameter\reflectionToParameters; +use function Chevere\Parameter\reflectionToReturn; + +$reflection = new ReflectionFunction('myFunction'); +$parameters = reflectionToParameters($reflection); +$return = reflectionToReturn($reflection); +$parameters(...$args); // valid $args +$result = myFunction(...$args); // myFunction call +$return($result); // valid $result +``` + +Use [attribute inline validation](#attribute-inline-validation) for manual validation within the function body: + +```php +use Chevere\Parameter\Attributes\IntAttr; +use Chevere\Parameter\Attributes\ReturnAttr; +use Chevere\Parameter\Attributes\StringAttr; +use function Chevere\Parameter\valid; +use function Chevere\Parameter\returnAttr; + +#[ReturnAttr( + new StringAttr('/ok$/') +)] +function myFunction( + #[IntAttr(min: 1, max: 10)] + int $var +): string +{ + valid(); // valid $var + $return = 'ok'; + + return returnAttr()($return); // valid $return +} +``` + +### CallableAttr + +Attributes in PHP only support expressions you can use on class constants. Is not possible to directly define dynamic parameters using attributes. + +To avoid this limitation you can use `CallableAttr` attribute which enables to forward parameter resolution to a callable returning a `ParameterInterface` instance. + +```php +use Chevere\Parameter\Interfaces\ParameterInterface; +use Chevere\Parameter\Attributes\CallableAttr; + +function myCallable(): ParameterInterface +{ + return arrayp( + email: string(), + )->withOptional( + name: string(), + ); +} + +#[CallableAttr('myCallable')] +``` + +## Parameter types + +A Parameter is an object implementing `ParameterInterface`. There are several Parameter types, each one with its own validation rules. Every Parameter can define a `description` and a `default` value, plus additional validation rules depending on the type. + +A Parameter can be defined using functions and/or attributes, it takes the same arguments for both. Use attributes when needing to define rules for parameters and return value. + +When invoking a Parameter it will trigger validation against the passed argument. + +## String + +Use function `string` to create a `StringParameter`. Pass a `regex` for string matching. + +```php +use function Chevere\Parameter\string; + +// Any string +$string = string(); +// String matching bin- +$string = string('/^bin-[\d]+$/'); +$string('bin-123'); +``` + +Use `StringAttr` attribute to define a string parameter. + +```php +use Chevere\Parameter\Attributes\StringAttr; + +#[StringAttr('/^bin-[\d]+$/')] +``` + +## String pseudo-parameters + +The following parameters are based on String. + +### Enum string + +Use function `enum` to create a `StringParameter` matching a list of strings. + +```php +use function Chevere\Parameter\enum; + +$enum = enum('on', 'off'); +$enum('on'); +$enum('off'); +``` + +Use `EnumAttr` attribute to define an enum string parameter. + +```php +use Chevere\Parameter\Attributes\EnumAttr; + +#[EnumAttr('on', 'off')] +``` + +### Int string + +Use function `intString` to create a `StringParameter` matching a string integers. + +```php +use function Chevere\Parameter\intString; + +$int = intString(); +$int('100'); +``` + +### Bool string + +Use function `boolString` to create a `StringParameter` matching `0` and `1` strings. + +```php +use function Chevere\Parameter\boolString; + +$bool = boolString(); +$bool('0'); +$bool('1'); +``` + +### Date string + +Use function `date` to create a `StringParameter` matching `YYYY-MM-DD` strings. + +```php +use function Chevere\Parameter\date; + +$date = date(); +$date('2021-01-01'); +``` + +### Time string + +Use function `time` to create a `StringParameter` matching `hh:mm:ss` strings. + +```php +use function Chevere\Parameter\time; + +$time = time(); +$time('12:00:00'); +``` + +### Datetime string + +Use function `datetime` to create a `StringParameter` matching `YYYY-MM-DD hh:mm:ss` strings. + +```php +use function Chevere\Parameter\datetime; + +$datetime = datetime(); +$datetime('2024-01-09 10:53:00'); +``` + +## Int + +Use function `int` to create a `IntParameter`. Pass `min` and `max` values for integer range, `accept` for a list of accepted integers and `reject` for a list of rejected integers. + +```php +use function Chevere\Parameter\int; + +// Any int +$int = int(); +$int(1); +// Integer between 0 and 100 +$int = int(min: 0, max: 100); +$int(50); +// Integer matching 1, 2 or 3 +$int = int(accept: [1, 2, 3]); +$int(2); +// Integer not-matching 1, 2 or 3 +$int = int(reject: [1, 2, 3]); +$int(4); +``` + +Use `IntAttr` attribute to define an integer parameter. + +```php +use Chevere\Parameter\Attributes\IntAttr; + +#[IntAttr(min: 0, max: 100)] +``` + +## Int pseudo-parameters + +The following parameters are based on Int. + +### Bool int + +Use function `boolInt` to create a `IntParameter` matching `0` and `1` integers. + +```php +use function Chevere\Parameter\boolInt; + +$bool = boolInt(); +$bool(0); +$bool(1); +``` + +## Float + +Use function `float` to create a `FloatParameter`. Pass `min` and `max` values for float range, `accept` for a list of accepted floats and `reject` for a list of rejected floats. + +```php +use function Chevere\Parameter\float; + +// Any float +$float = float(); +$float(1.5); +// Float between 0 and 100 +$float = float(min: 0, max: 100); +$float(50.5); +// Float matching 1.5, 2.5 or 3.5 +$float = float(accept: [1.5, 2.5, 3.5]); +$float(2.5); +// Float not-matching 1.5, 2.5 or 3.5 +$float = float(reject: [1.5, 2.5, 3.5]); +$float(4.5); +``` + +Use `FloatAttr` attribute to define a float parameter. + +```php +use Chevere\Parameter\Attributes\FloatAttr; + +#[FloatAttr(min: 0, max: 100)] +``` + +## Bool + +Use function `bool` to create a `BoolParameter`. + +```php +use function Chevere\Parameter\bool; + +$bool = bool(); +$bool(true); +$bool(false); +``` + +Use `BoolAttr` attribute to define a bool parameter. + +```php +use Chevere\Parameter\Attributes\BoolAttr; + +#[BoolAttr] +``` + +## Null + +Use function `null` to create a `NullParameter`. + +```php +use function Chevere\Parameter\null; + +$null = null(); +$null(null); +``` + +Use `NullAttr` attribute to define a null parameter. + +```php +use Chevere\Parameter\Attributes\NullAttr; + +#[NullAttr] +``` + +## Object + +Use function `object` to create a `ObjectParameter`. Pass a className for the object class name. + +```php +use function Chevere\Parameter\object; + +$object = object(stdClass::class); +$object(new stdClass()); +``` + +Use `ObjectAttr` attribute to define an object parameter. + +```php +use Chevere\Parameter\Attributes\ObjectAttr; + +#[ObjectAttr(stdClass::class)] +``` + +## Mixed + +Use function `mixed` to create a `MixedParameter`. + +```php +use function Chevere\Parameter\mixed; + +$mixed = mixed(); +$mixed(1); +$mixed('1'); +$mixed(true); +$mixed(null); +``` + +## Union + +Use function `union` to create a `UnionParameter`. Pass a list of parameters to match, target value must match at least one. + +```php +use function Chevere\Parameter\union; + +// Any string or null +$union = union(string(), null()); +$union('abc'); +$union(null); +// Any digit string or any integer +$union = union( + intString(), + integer() +); +$union('100'); +$union(100); +``` + +## Array + +Parameter for type `array` is handled as a composite Parameter holding parameter definition for **each one** of its members. + +Use function `arrayp` to create an `ArrayParameter` for named arguments as required array keys. + +```php +use function Chevere\Parameter\arrayp; + +// Empty array +$array = arrayp(); +$array([]); +// Required 'a' => +$array = arrayp(a: string()); +$array(['a' => 'Hello world']); +``` + +Parameter supports nested arrays of any depth: + +```php +use function Chevere\Parameter\arrayp; +use function Chevere\Parameter\float; +use function Chevere\Parameter\int; + +$array = arrayp( + id: int(min: 0), + items: arrayp( + id: int(min: 0), + price: float(min: 0), + ), +); +$array([ + 'id' => 1, + 'items' => [ + 'id' => 25, + 'price' => 16.5, + ] +]); +``` + +Use `ArrayAttr` attribute to define an array parameter. + +```php +use Chevere\Parameter\Attributes\ArrayAttr; +use Chevere\Parameter\Attributes\StringAttr; + +#[ArrayAttr( + a: new StringAttr(), +)] +``` + +### With required + +use method `withRequired` to define required parameters. + +```php +$array = $array + ->withRequired( + username: string(), + email: string() + ); +``` + +### With optional + +use method `withOptional` to define optional parameters. + +```php +$array = $array + ->withOptional(address: string()); +``` + +👉 **Note:** Optional parameters will be validated only if a matching key is provided. + +### With modify + +use method `withModify` to define modify parameters. + +```php +$array = $array + ->withModify( + username: string('/\w+/'), + ); +``` + +### With make optional + +use method `withMakeOptional` to make required parameters optional. + +```php +$array = $array + ->withMakeOptional('username'); +``` + +### With make required + +use method `withMakeRequired` to make optional parameters required. + +```php +$array = $array + ->withMakeRequired('email'); +``` + +### Without + +use method `without` to remove parameters. + +```php +$array = $array + ->without('a'); +``` + +### With optional minimum + +use method `withOptionalMinimum` to define a minimum number of optional parameters. Useful if all parameters are optional but 1. + +```php +$array = $array + ->withOptionalMinimum(1); +``` + +## Array pseudo-parameters + +The following parameters are based on Array. + +### Array String + +Use function `arrayString` to create an `ArrayStringParameterInterface` for string values. It only supports string parameters. + +```php +use function Chevere\Parameter\arrayString; +use function Chevere\Parameter\string; + +$array = arrayString( + test: string(), +); +$array(['test' => 'foo']); +``` + +### File + +Use function `file` to create an `ArrayParameter` for file uploads. + +```php +use function Chevere\Parameter\file; + +$array = file(); +$file = [ + 'name' => 'foo.txt', + 'type' => 'text/plain', + 'tmp_name' => '/tmp/phpYzdqkD', + 'error' => 0, + 'size' => 123, +]; +$array($file); +``` + +By default it provides validation for `$_FILES` shape, but you can define your own validation rules. For example, to validate name and contents: + +```php +use function Chevere\Parameter\file; + +$array = file( + name: string('/^\.txt$/'), + contents: string('/wage-/'), +); +$array( + 'name' => 'wage-2024.txt', + 'type' => 'text/plain', + 'tmp_name' => '/tmp/phpYzdqkD', + 'error' => 0, + 'size' => 27, + 'contents' => 'yada yada wage-2024 bla bla', +); +``` + +## Iterable + +Iterable type `Traversable|array` is considered as a composite Parameter holding a generic definition for key and value. Parameter enables to describe this collection of items sharing the same shape. + +Use function `iterable` to create an `IterableParameter`. Pass a `V` and `K` parameters for generic key and value. + +```php +use function Chevere\Parameter\int; +use function Chevere\Parameter\iterable; + +$iterable = iterable(int(min: 0)); +$iterable([0, 1, 2, 3]); +``` + +It also works with named keys: + +```php +use function Chevere\Parameter\int; +use function Chevere\Parameter\iterable; +use function Chevere\Parameter\string; + +$iterable = iterable( + V: arrayp( + id: int(min: 0), + name: string('^[\w]{1,255}'), + ) + K: string(), +); +$iterable([ + 'based' => [ + 'id' => 1, + 'name' => 'OscarGangas' + ], + 'fome' => [ + 'id' => 2, + 'name' => 'BomboFica' + ], +]); +``` + +## Cookbook + +### Inline validation + +* Validate string starting with "a": + +```php +use function Chevere\Parameter\string; + +$value = 'ahhh'; +string('/^a.+/')($value); +``` + +* Validate an int of min value `100`: + +```php +use function Chevere\Parameter\int; + +$value = 100; +int(min: 100)($value); +``` + +* Validate an int accept list: + +```php +use function Chevere\Parameter\int; + +$value = 1; +int(accept: [1, 2, 3])($value); +``` + +* Validate a float reject list: + +```php +use function Chevere\Parameter\float; + +$value = 3.1; +float(reject: [1.1, 2.1])($value); +``` + +* Validate an array: + +```php +use function Chevere\Parameter\arrayp; +use function Chevere\Parameter\int; +use function Chevere\Parameter\string; + +$value = [ + 'id' => 1, + 'name' => 'Pepe' +]; +arrayp( + id: int(min: 1), + name: string('/^[A-Z]{1}\w+$/') +)($value); +``` + +* Validate an iterable `int` list: + +```php +use function Chevere\Parameter\int; +use function Chevere\Parameter\iterable; + +$value = [1, 2, 3]; +iterable(int())($value); +``` + +* Validate an iterable int list with string key type rules: + +```php +use function Chevere\Parameter\int; +use function Chevere\Parameter\iterable; + +$value = [ + 'unila' => 1, + 'dorila' => 2, + 'tirifila' => 3, +]; +iterable( + K: string('/ila$/'), + V: int(min: 1) +)($value); +``` + +* Validate an union of type ?int: + +```php +use function Chevere\Parameter\int; +use function Chevere\Parameter\null; + +$value = 1; +union(int(), null())($value); +``` + +### Attribute delegated validation + +* Use function `validated()` to get a return validated against all rules. + +```php +use function Chevere\Parameter\validated; + +$result = validated('myFunction', $var); +``` + +* Use function `reflectionToParameters()` to get rules for validating arguments. + +```php +use ReflectionMethod; +use Chevere\Parameter\Attributes\IntAttr; +use function Chevere\Parameter\arguments; +use function Chevere\Parameter\reflectionToParameters; + +$class = new class() { + public function wea( + #[IntAttr(accept: [1, 10, 100])] + int $base + ): void { + } +}; +$object = new $class(); +$reflection = new ReflectionMethod($object, 'wea'); +$parameters = reflectionToParameters($reflection); +$args = ['base' => 10]; +$parameters(...$args); // valid $args +$result = $object->wea(...$args); +``` + +* Use function `reflectionToReturn()` to get rules for validating function/method return value: + +```php +use ReflectionFunction; +use Chevere\Parameter\Attributes\IntAttr; +use Chevere\Parameter\Attributes\ReturnAttr; +use function Chevere\Parameter\reflectionToReturn; + +$function = + #[ReturnAttr( + new IntAttr(min: 1000) + )] + function (int $base): int { + return 10 * $base; + }; +$reflection = new ReflectionFunction($function); +$return = reflectionToReturn($reflection); +$base = 10; +$result = $function($base); +$result = $return($result); // Validates result +``` + +### Attribute inline validation + +Use `valid()` on the function/method body to trigger validation for arguments. + +* Validate an string enum for `Hugo`, `Paco`, `Luis`: +* Validate a min float value of `1000`: + +```php +use Chevere\Parameter\Attributes\EnumAttr; +use function Chevere\Parameter\validate; + +function myEnum( + #[EnumAttr('Hugo', 'Paco', 'Luis')] + string $name, + #[FloatAttr(min: 1000)] + float $money +): void +{ + valid(); + // Or single... + valid('name'); + valid('money'); +} +$arg1 = 'Paco'; +$arg2 = 1000.50; +myEnum($arg1, $arg2); +``` + +* Validate an int of any value but `0` and `100`: + +```php +use Chevere\Parameter\Attributes\IntAttr; +use function Chevere\Parameter\validate; + +function myInt( + #[IntAttr(reject: [0, 100])] + int $id +): void +{ + valid(); +} +$value = 50; +myInt($value); +``` + +* Validate a ~~nasty~~ nested array: + +```php +use Chevere\Parameter\Attributes\ArrayAttr; +use Chevere\Parameter\Attributes\IntAttr; +use Chevere\Parameter\Attributes\StringAttr; +use Chevere\Parameter\Attributes\IterableAttr; +use function Chevere\Parameter\validate; + +function myArray( + #[ArrayAttr( + id: new IntAttr(min: 1), + role: new ArrayAttr( + mask: new IntAttr(accept: [64, 128, 256]), + name: new StringAttr('/[a-z]+/'), + tenants: new IterableAttr( + new IntAttr(min: 1) + ) + ), + )] + array $spooky +): void +{ + valid(); +} +$value = [ + 'id' => 10, + 'role' => [ + 'mask' => 128, + 'name' => 'admin', + 'tenants' => [1, 2, 3, 4, 5] + ], +]; +myArray($value); +``` + +* Validate iterable int list: + +```php +use Chevere\Parameter\Attributes\IntAttr; +use Chevere\Parameter\Attributes\IterableAttr; +use function Chevere\Parameter\validate; + +function myIterable( + #[IterableAttr( + new IntAttr(), + )] + array $list = [0,1,2] +): void +{ + valid(); +} +``` + +Use function `returnAttr()` on the function/method body. + +* Validate int [min: 0, max: 5] return: + +```php +use Chevere\Parameter\Attributes\IntAttr; +use Chevere\Parameter\Attributes\ReturnAttr; +use function Chevere\Parameter\returnAttr; + +#[ReturnAttr( + new IntAttr(min: 0, max: 5) +)] +public function myReturnInt(): int +{ + $result = 1; + + return returnAttr()($result); +} +``` + +* Validate array return: + +```php +use Chevere\Parameter\Attributes\ArrayAttr; +use Chevere\Parameter\Attributes\IntAttr; +use Chevere\Parameter\Attributes\StringAttr; +use Chevere\Parameter\Attributes\ReturnAttr; +use function Chevere\Parameter\returnAttr; + +#[ReturnAttr( + new ArrayAttr( + id: new IntAttr(min: 0), + name: new StringAttr() + ) +)] +public function myReturnArray(): array +{ + $result = [ + 'id' => 1, + 'name' => 'Peoples Hernandez' + ]; + + return returnAttr()($result); +} +``` + +💡 By convention when omitting `ReturnAttr` the method `public static function return(): ParameterInterface` (if any) will be used to determine return validation rules. diff --git a/src/packages/parameter/parameter-logo.svg b/src/packages/parameter/parameter-logo.svg new file mode 100644 index 0000000..5e775c9 --- /dev/null +++ b/src/packages/parameter/parameter-logo.svg @@ -0,0 +1,8 @@ + + + + + + + +