modifs.mineures sans commentaires

This commit is contained in:
Jephté Clain 2025-03-18 10:35:28 +04:00
parent 62987d576e
commit 1feffb6c0f
5 changed files with 96 additions and 90 deletions

View File

@ -17,6 +17,29 @@ use nur\sery\wip\schema\types\tcontent;
use nur\sery\wip\schema\types\tpkey;
use nur\sery\wip\schema\types\trawstring;
/**
* Class Schema
*
* @property-read array|IType $type
* @property-read mixed $default
* @property-read string|null $title
* @property-read bool $required
* @property-read bool $nullable
* @property-read string|array|null $desc
* @property-read callable|null $analyzerFunc
* @property-read callable|null $extractorFunc
* @property-read callable|null $parserFunc
* @property-read callable|null $normalizerFunc
* @property-read array|null $messages
* @property-read callable|null $formatterFunc
* @property-read mixed $format
* @property-read array $nature
* @property-read array|null $schema
* @property-read string|int|null $name
* @property-read string|array|null $pkey
* @property-read string|null $header
* @property-read bool|null $computed
*/
abstract class Schema implements ArrayAccess {
/**
* créer le cas échéant une nouvelle instance de {@link Schema} à partir d'une
@ -253,6 +276,8 @@ abstract class Schema implements ArrayAccess {
/** retourner true si le schéma est de nature scalaire */
function isScalar(?ScalarSchema &$schema=null): bool { return false; }
abstract protected function newWrapper(): Wrapper;
abstract function getWrapper(&$value=null, $valueKey=null, ?Wrapper &$wrapper=null): Wrapper;
#############################################################################
@ -272,7 +297,15 @@ abstract class Schema implements ArrayAccess {
throw AccessException::read_only(null, $offset);
}
const _PROPERTY_PKEYS = [];
const _PROPERTY_PKEYS = [
"analyzerFunc" => "analyzer_func",
"extractorFunc" => "extractor_func",
"parserFunc" => "parser_func",
"normalizerFunc" => "normalizer_func",
"formatterFunc" => "formatter_func",
"nature" => ["", 0],
];
function __get($name) {
$pkey = cl::get(static::_PROPERTY_PKEYS, $name, $name);
return cl::pget($this->definition, $pkey);

View File

@ -1,6 +1,5 @@
# nulib\schema
* instance de WrapperContext directement dans le schéma
* 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

View File

@ -5,26 +5,31 @@ use nur\sery\wip\schema\input\Input;
use nur\sery\wip\schema\types\IType;
class WrapperContext {
function __construct(Schema $schema, Wrapper $wrapper, Input $input, $valueKey, Result $result) {
function __construct(Schema $schema, Wrapper $wrapper, ?Input $input, $valueKey, Result $result) {
$this->schema = $schema;
$this->wrapper = $wrapper;
$this->input = $input;
$this->result = $result;
if ($input !== null) $this->input = $input;
$this->valueKey = $valueKey;
$this->type = null;
$this->result = $result;
$this->origValue = null;
$this->value = null;
$this->valueKey = $valueKey;
}
/** schéma de la valeur */
public Schema $schema;
/** instance de Wrapper associé à ce contexte */
public Wrapper $wrapper;
/** source et destination de la valeur */
public Input $input;
public Result $result;
/** @var string|int|null clé de la valeur dans le tableau destination */
public $valueKey;
/** type de la valeur après analyse */
public ?IType $type;
/** résultat de l'analyse de la valeur */
public Result $result;
/** @var mixed */
public $origValue;
/** @var mixed */
public $value;
/** @var int|string|null */
public $valueKey;
}

View File

@ -8,26 +8,6 @@ use nur\sery\wip\schema\Wrapper;
/**
* Class ScalarSchema
*
* @property-read array|IType $type
* @property-read mixed $default
* @property-read string|null $title
* @property-read bool $required
* @property-read bool $nullable
* @property-read string|array|null $desc
* @property-read callable|null $analyzerFunc
* @property-read callable|null $extractorFunc
* @property-read callable|null $parserFunc
* @property-read callable|null $normalizerFunc
* @property-read array|null $messages
* @property-read callable|null $formatterFunc
* @property-read mixed $format
* @property-read array $nature
* @property-read array|null $schema
* @property-read string|int|null $name
* @property-read string|array|null $pkey
* @property-read string|null $header
* @property-read bool|null $composite
*/
class ScalarSchema extends Schema {
/** @var array meta-schema d'un schéma de nature scalaire */
@ -97,16 +77,4 @@ class ScalarSchema extends Schema {
if (!($wrapper instanceof ScalarWrapper)) $wrapper = $this->newWrapper();
return $wrapper->reset($value, $valueKey, $verifix);
}
#############################################################################
# key & properties
const _PROPERTY_PKEYS = [
"analyzerFunc" => "analyzer_func",
"extractorFunc" => "extractor_func",
"parserFunc" => "parser_func",
"normalizerFunc" => "normalizer_func",
"formatterFunc" => "formatter_func",
"nature" => ["", 0],
];
}

View File

@ -19,35 +19,21 @@ class ScalarWrapper extends Wrapper {
# c'est une initialisation sans conséquences
$throw = true;
}
$this->context = new WrapperContext($schema, $this, null, null, new ScalarResult());
$this->verifix = $verifix;
$this->throw = $throw ?? false;
$this->schema = $schema;
$this->result = new ScalarResult();
$this->reset($value, $valueKey);
$this->throw = $throw ?? true;
}
function isScalar(?ScalarWrapper &$wrapper=null): bool { $wrapper = $this; return true; }
protected WrapperContext $context;
protected bool $verifix;
protected bool $throw;
/** schéma de cette valeur */
protected ScalarSchema $schema;
/** source et destination de la valeur */
protected Input $input;
/** @var string|int|null clé de la valeur dans le tableau destination */
protected $valueKey;
/** type de la valeur après analyse */
protected ?IType $type;
/** résultat de l'analyse de la valeur */
protected ScalarResult $result;
protected function newInput(&$value): Input {
return new Input($value);
}
@ -55,9 +41,9 @@ class ScalarWrapper extends Wrapper {
function reset(&$value, $valueKey=null, ?bool $verifix=null): Wrapper {
if ($value instanceof Input) $input = $value;
else $input = $this->newInput($value);
$this->input = $input;
$this->valueKey = $valueKey;
$this->type = null;
$this->context->input = $input;
$this->context->valueKey = $valueKey;
$this->context->type = null;
$this->analyze();
if ($verifix ?? $this->verifix) $this->verifix();
return $this;
@ -74,7 +60,8 @@ class ScalarWrapper extends Wrapper {
}
/** analyser la valeur et résoudre son type */
protected function analyze0(WrapperContext $context): int {
protected function analyze0(): int {
$context = $this->context;
/** @var ScalarSchema $schema */
$schema = $context->schema;
$input = $context->input;
@ -112,7 +99,7 @@ class ScalarWrapper extends Wrapper {
$args = $name;
$name = $key;
}
$type = types::get($schema->nullable, $name, $args, $this->schema->getDefinition());
$type = types::get($schema->nullable, $name, $args, $schema->getDefinition());
if ($firstType === null) $firstType = $type;
$types[] = $type;
if ($type->isAvailable($input, $valueKey)) {
@ -166,17 +153,19 @@ class ScalarWrapper extends Wrapper {
}
protected function analyze(): int {
$schema = $this->schema;
$input = $this->input;
$valueKey = $this->valueKey;
$result = $this->result;
$context = $this->context;
/** @var ScalarSchema $schema */
$schema = $context->schema;
$input = $context->input;
$valueKey = $context->valueKey;
/** @var ScalarResult $result */
$result = $context->result;
$result->reset();
$context = new WrapperContext($schema, $this, $input, $valueKey, $result);
/** @var func $analyzerFunc */
$analyzerFunc = $schema->analyzerFunc;
if ($analyzerFunc !== null) $what = $analyzerFunc->invoke([$context]);
else $what = $this->analyze0($context);
else $what = $this->analyze0();
if ($what !== ref_analyze::STRING) return $what;
$value = $context->value;
@ -212,20 +201,27 @@ class ScalarWrapper extends Wrapper {
}
function verifix(?bool $throw=null): bool {
$result = $this->result;
$valueKey = $this->valueKey;
$context = $this->context;
/** @var ScalarSchema $schema */
$schema = $context->schema;
$input = $context->input;
$valueKey = $context->valueKey;
/** @var ScalarResult $result */
$result = $context->result;
$verifix = false;
$modified = false;
if ($result->resultAvailable) {
if ($result->null) {
# forcer la valeur null, parce que la valeur actuelle est peut-être une
# valeur assimilée à null
$this->input->set(null, $valueKey);
$input->set(null, $valueKey);
} elseif ($result->valid && !$result->normalized) {
$normalizedValue = $result->normalizedValue;
if ($normalizedValue !== null) {
# la valeur normalisée est disponible
$this->input->set($normalizedValue);
$input->set($normalizedValue);
$result->normalizedValue = null;
$modified = true;
} else {
@ -238,75 +234,80 @@ class ScalarWrapper extends Wrapper {
}
if ($verifix) {
$value = $this->input->get($valueKey);
$schema = $this->schema;
$value = $input->get($valueKey);
/** @var func $normalizerFunc */
$normalizerFunc = $schema->normalizerFunc;
if ($normalizerFunc !== null) {
$context = new WrapperContext($schema, $this, $this->input, $valueKey, $result);
$context = new WrapperContext($schema, $this, $input, $valueKey, $result);
$orig = $value;
$value = $normalizerFunc->invoke([$orig, $context]);
$modified = $value !== $orig;
} else {
$modified = $this->type->verifix($value, $result, $this->schema);
$modified = $this->type->verifix($value, $result, $schema);
}
if ($result->valid) $this->input->set($value, $valueKey);
if ($result->valid) $input->set($value, $valueKey);
}
if (!$result->valid) $result->throw($throw ?? $this->throw);
return $modified;
}
function getResult(): ScalarResult {
return $this->result;
/** @var ScalarResult $result */
$result = $this->context->result;
return $result;
}
function isPresent(): bool {
return $this->result->present;
return $this->context->result->present;
}
function getType(): IType {
return $this->type;
return $this->context->type;
}
function isAvailable(): bool {
return $this->result->available;
return $this->context->result->available;
}
function isValid(): bool {
return $this->result->valid;
return $this->context->result->valid;
}
function isNormalized(): bool {
return $this->result->normalized;
return $this->context->result->normalized;
}
function get($default=null) {
if ($this->result->available) return $this->input->get($this->valueKey);
$context = $this->context;
if ($context->result->available) return $context->input->get($context->valueKey);
else return $default;
}
function set($value, ?bool $verifix=null): ScalarWrapper {
$this->input->set($value, $this->valueKey);
$context = $this->context;
$context->input->set($value, $context->valueKey);
$this->analyze();
if ($verifix ?? $this->verifix) $this->verifix();
return $this;
}
function unset(?bool $verifix=null): ScalarWrapper {
$this->input->unset($this->valueKey);
$context = $this->context;
$context->input->unset($context->valueKey);
$this->analyze();
if ($verifix ?? $this->verifix) $this->verifix();
return $this;
}
function format($format=null): string {
$value = $this->input->get($this->valueKey);
$context = $this->context;
$value = $context->input->get($context->valueKey);
/** @var func $formatterFunc */
$formatterFunc = $this->schema->formatterFunc;
$formatterFunc = $context->schema->formatterFunc;
if ($formatterFunc !== null) {
# la fonction formatter n'a pas forcément accès au format de la définition
# le lui fournir ici
$format ??= $this->schema->format;
$format ??= $context->schema->format;
return $formatterFunc->invoke([$value, $format]);
} else {
# on assume que le type a été initialisé avec le format de la définition