diff --git a/src/schema/TODO.md b/src/schema/TODO.md index 1aea69f..46e80ce 100644 --- a/src/schema/TODO.md +++ b/src/schema/TODO.md @@ -1,6 +1,5 @@ # nulib\schema -* renommer AnalyzerContext en WrapperContext * plus de {key} ni {orig} dans messages * les messages standard ne sont utilisés que s'il n'y a pas de message dans l'exception @@ -14,32 +13,6 @@ * tdate et tdatetime. qu'en est-il des autres classes (delay, etc.) * possibilité de spécifier le format de la date à analyser * ScalarSchema::from_property() -* possibilité de spécifier un type via sa classe, e.g - ~~~php - Schema::ns($schema, [ - MyType::class, null, "une valeur de type MyType" - ]); - # ou - Schema::ns($schema, [ - [MyType::class => $params], null, "une valeur de type MyType" - ]); - ~~~ - MyType doit implémenter IType -* possibilité de spécifier une instance de type, e.g - ~~~php - Schema::ns($schema, [ - new MyType(), null, "une valeur de type MyType" - ]); - ~~~ - MyType doit implémenter IType -* type générique construit à partir d'un nom de classe, e.g - ~~~php - Schema::ns($schema, [ - MyClass::class, null, "une valeur de type MyClass" - ]); - ~~~ - MyClass ne doit pas implémenter IType, et le type correspondant est créé avec - `new tgeneric(MyClass::class)` * dans AssocSchema, support `[key_prefix]` qui permet de spécifier un préfixe commun aux champs dans le tableau destination, e.g diff --git a/src/schema/AnalyzerContext.php b/src/schema/WrapperContext.php similarity index 96% rename from src/schema/AnalyzerContext.php rename to src/schema/WrapperContext.php index 3136c04..5ee0d37 100644 --- a/src/schema/AnalyzerContext.php +++ b/src/schema/WrapperContext.php @@ -4,7 +4,7 @@ namespace nur\sery\wip\schema; use nur\sery\wip\schema\input\Input; use nur\sery\wip\schema\types\IType; -class AnalyzerContext { +class WrapperContext { function __construct(Schema $schema, Wrapper $wrapper, Input $input, $valueKey, Result $result) { $this->schema = $schema; $this->wrapper = $wrapper; diff --git a/src/schema/_scalar/ScalarWrapper.php b/src/schema/_scalar/ScalarWrapper.php index bfd0a81..0ea9596 100644 --- a/src/schema/_scalar/ScalarWrapper.php +++ b/src/schema/_scalar/ScalarWrapper.php @@ -4,7 +4,7 @@ namespace nur\sery\wip\schema\_scalar; use nulib\php\func; use nulib\ref\schema\ref_analyze; use nulib\ValueException; -use nur\sery\wip\schema\AnalyzerContext; +use nur\sery\wip\schema\WrapperContext; use nur\sery\wip\schema\input\Input; use nur\sery\wip\schema\types; use nur\sery\wip\schema\types\IType; @@ -74,7 +74,7 @@ class ScalarWrapper extends Wrapper { } /** analyser la valeur et résoudre son type */ - protected function analyze0(AnalyzerContext $context): int { + protected function analyze0(WrapperContext $context): int { /** @var ScalarSchema $schema */ $schema = $context->schema; $input = $context->input; @@ -171,7 +171,7 @@ class ScalarWrapper extends Wrapper { $valueKey = $this->valueKey; $result = $this->result; $result->reset(); - $context = new AnalyzerContext($schema, $this, $input, $valueKey, $result); + $context = new WrapperContext($schema, $this, $input, $valueKey, $result); /** @var func $analyzerFunc */ $analyzerFunc = $schema->analyzerFunc; @@ -243,7 +243,7 @@ class ScalarWrapper extends Wrapper { /** @var func $normalizerFunc */ $normalizerFunc = $schema->normalizerFunc; if ($normalizerFunc !== null) { - $context = new AnalyzerContext($schema, $this, $this->input, $valueKey, $result); + $context = new WrapperContext($schema, $this, $this->input, $valueKey, $result); $orig = $value; $value = $normalizerFunc->invoke([$orig, $context]); $modified = $value !== $orig; diff --git a/src/schema/types.php b/src/schema/types.php index 7e3442a..c1b618b 100644 --- a/src/schema/types.php +++ b/src/schema/types.php @@ -1,6 +1,7 @@ get($nullable, $name, $args, $definition); } diff --git a/src/schema/types/IType.php b/src/schema/types/IType.php index a245fd7..36f5fd4 100644 --- a/src/schema/types/IType.php +++ b/src/schema/types/IType.php @@ -10,6 +10,8 @@ use nur\sery\wip\schema\Schema; * Interface IType: un type de données */ interface IType { + static function get_params_from_definition(?array $definition): ?array; + /** * obtenir, pour information, le nom officiel de ce type, utilisable dans une * définition de schéma diff --git a/src/schema/types/Registry.php b/src/schema/types/Registry.php index eb16596..e7bdecd 100644 --- a/src/schema/types/Registry.php +++ b/src/schema/types/Registry.php @@ -3,6 +3,7 @@ namespace nur\sery\wip\schema\types; use nulib\cl; use nulib\php\func; +use nulib\ValueException; class Registry { const TYPES = [ @@ -31,8 +32,6 @@ class Registry { protected $types; function get(bool $nullable, ?string $name, ?array $args=null, ?array $definition=null): IType { - $name ??= "raw"; - $class = self::TYPES[$name]; if (cl::is_list($args)) { $key = array_key_last($args); $params = $args[$key]; @@ -41,6 +40,16 @@ class Registry { $params = $args; $args = null; } + $name ??= "raw"; + $class = cl::get(self::TYPES, $name); + if ($class === null) { + $class = $name; + if (!class_exists($class)) { + throw ValueException::invalid_type($class, IType::class); + } elseif (!is_subclass_of($class, IType::class)) { + return new tgeneric($class, $nullable, $params); + } + } $params = cl::merge($class::get_params_from_definition($definition), $params); if ($args || $params !== null) { $args ??= []; diff --git a/src/schema/types/tgeneric.php b/src/schema/types/tgeneric.php new file mode 100644 index 0000000..16f86a8 --- /dev/null +++ b/src/schema/types/tgeneric.php @@ -0,0 +1,52 @@ +class = $class; + parent::__construct($nullable, $params); + } + + protected string $class; + + function getClass(): string { + return $this->class; + } + + function isAvailable(Input $input, $valueKey): bool { + return $input->isAvailable($valueKey); + } + + public function isNull($value): bool { + return $value === null; + } + + function isValid($value, ?bool &$normalized=null): bool { + $normalized = true; + return $value instanceof $this->class; + } + + function parse(string $value) { + throw ValueException::invalid_type($value, $this->class); + } + + /** + * @var ScalarResult $result + * @var ScalarSchema $schema + */ + function verifix(&$value, Result $result, Schema $schema): bool { + $result->setNormalized(); + return false; + } + + function format($value, $format=null): string { + return strval($value); + } +} diff --git a/src/schema/types/tmixed.php b/src/schema/types/tmixed.php index 5f387c6..fa525eb 100644 --- a/src/schema/types/tmixed.php +++ b/src/schema/types/tmixed.php @@ -41,6 +41,6 @@ class tmixed extends _tsimple { } function format($value, $format=null): string { - return var_export($value, true); + return strval($value); } }