modifs.mineures sans commentaires

This commit is contained in:
Jephté Clain 2023-11-25 10:04:24 +04:00
parent 80877faba1
commit ad739c5e44
17 changed files with 127 additions and 73 deletions

8
TODO.md Normal file
View File

@ -0,0 +1,8 @@
# TODO
## schema
* [ ] properties dans ScalarSchema, avec aliases pour notamment "nature" => ""
* [ ] remplacer IValue et TValue par une classe abstraite Value
-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary

View File

@ -183,10 +183,10 @@ const VALUE_SCHEMA = [
"title" => "libellé de la valeur", "title" => "libellé de la valeur",
"required" => false, "required" => false,
"nullable" => true, "nullable" => true,
"desc" => description de la valeur, "desc" => "description de la valeur",
"name" => "identifiant de la valeur", "name" => "identifiant de la valeur",
# spécifique à VALUE_SCHEMA # spécifique à VALUE_SCHEMA
"key" => ""chemin de clé de la valeur dans le tableau associatif", "key" => "chemin de clé de la valeur dans le tableau associatif",
], ],
]; ];
~~~ ~~~
@ -199,7 +199,7 @@ const VALUE_SCHEMA = [
"title" => "libellé de la valeur", "title" => "libellé de la valeur",
"required" => false, "required" => false,
"nullable" => true, "nullable" => true,
"desc" => description de la valeur, "desc" => "description de la valeur",
"name" => "identifiant de la valeur", "name" => "identifiant de la valeur",
# spécifique à VALUE_SCHEMA # spécifique à VALUE_SCHEMA
"key" => "chemin de clé de la valeur dans le tableau associatif", "key" => "chemin de clé de la valeur dans le tableau associatif",

View File

@ -38,7 +38,8 @@ class AssocSchema extends Schema {
$this->definition = $definition; $this->definition = $definition;
} }
function isAssoc(): bool { function isAssoc(?AssocSchema &$assoc=null): bool {
$assoc = $this;
return true; return true;
} }
} }

View File

@ -38,7 +38,8 @@ class ListSchema extends Schema {
$this->definition = $definition; $this->definition = $definition;
} }
function isList(): bool { function isList(?ListSchema &$list=null): bool {
$list = $this;
return true; return true;
} }
} }

View File

@ -5,21 +5,9 @@ use nur\sery\schema\input\Input;
use nur\sery\schema\values\AssocValue; use nur\sery\schema\values\AssocValue;
use nur\sery\schema\values\IValue; use nur\sery\schema\values\IValue;
use nur\sery\schema\values\ScalarValue; use nur\sery\schema\values\ScalarValue;
use nur\sery\schema\values\SeqValue; use nur\sery\schema\values\ListValue;
use nulib\StateException; use nulib\StateException;
#XXX
# analyze() et [analyzer_func] --> indique ce qu'est la valeur qu'on vérifixe
# retourne MISSING (la valeur n'existe pas)
# NULL (la valeur existe mais est nulle)
# STRING (la valeur est une chaine qu'il faut parser)
# INVALID (la valeur n'est pas du bon type et il n'est pas possible de la convertir)
# VALID (la valeur est dans le bon type)
# extract() et [extractor_func] --> si analyze() retourne STRING, extraire la
# chaine à parser
# parse() et [parser_func] --> parser la chaine et retourner la valeur
# format() et [formatter_func] --> formatter la valeur et retourner une chaine
class OldSchema { class OldSchema {
/** /**
* @var bool true si toutes les clés du schéma doivent exister, avec leur * @var bool true si toutes les clés du schéma doivent exister, avec leur
@ -49,11 +37,11 @@ class OldSchema {
} }
/** retourner true la valeur est un tableau séquentiel */ /** retourner true la valeur est un tableau séquentiel */
function getSeq(&$value, $key=null, ?SeqValue &$seq=null): bool { function getList(&$value, $key=null, ?ListValue &$list=null): bool {
if (!$this->isSeq()) return false; if (!$this->isSeq()) return false;
if ($value instanceof Input) $input = $value; if ($value instanceof Input) $input = $value;
else $input = new Input($value); else $input = new Input($value);
$seq = new SeqValue($input, $this->schema, $key); $list = new ListValue($input, $this->schema, $key);
return true; return true;
} }
@ -67,9 +55,9 @@ class OldSchema {
} }
function getValue(&$value, $key=null): IValue { function getValue(&$value, $key=null): IValue {
if ($this->getScalar($input, $key, $scalar)) return $scalar; if ($this->getScalar($value, $key, $scalar)) return $scalar;
elseif ($this->getSeq($input, $key, $seq)) return $seq; elseif ($this->getList($value, $key, $seq)) return $seq;
elseif ($this->getAssoc($input, $key, $assoc)) return $assoc; elseif ($this->getAssoc($value, $key, $assoc)) return $assoc;
else throw StateException::unexpected_state(); else throw StateException::unexpected_state();
} }
} }

View File

@ -2,8 +2,11 @@
namespace nur\sery\schema; namespace nur\sery\schema;
use nulib\cl; use nulib\cl;
use nur\sery\schema\input\Input;
use nur\sery\schema\ref\ref_schema; use nur\sery\schema\ref\ref_schema;
use nur\sery\schema\ref\ref_types; use nur\sery\schema\ref\ref_types;
use nur\sery\schema\values\IValue;
use nur\sery\schema\values\ScalarValue;
/** /**
* Class ScalarSchema * Class ScalarSchema
@ -31,13 +34,7 @@ class ScalarSchema extends Schema {
"type", "default", "title", "required", "nullable", "desc", "type", "default", "title", "required", "nullable", "desc",
"analyzer_func", "extractor_func", "parser_func", "normalizer_func", "messages", "analyzer_func", "extractor_func", "parser_func", "normalizer_func", "messages",
"formatter_func", "format", "formatter_func", "format",
"", "name", "", "name", "key", "header", "composite",
];
const METASCHEMA_INDEXES = [
"type" => 0, "default" => 1, "title" => 2, "required" => 3, "nullable" => 4, "desc" => 5,
"analyzer_func" => 6, "extractor_func" => 7, "parser_func" => 8, "normalizer_func" => 9, "messages" => 10,
"formatter_func" => 11, "format" => 12,
"" => 13, "name" => 14,
]; ];
/** /**
@ -135,6 +132,18 @@ class ScalarSchema extends Schema {
throw SchemaException::invalid_schema("expected scalar nature"); throw SchemaException::invalid_schema("expected scalar nature");
} }
$definition[""] = $nature; $definition[""] = $nature;
# name, key, header
$name = $definition["name"];
$key = $definition["key"];
$header = $definition["header"];
self::ensure_nstring($name);
self::ensure_npkey($key);
self::ensure_nstring($header);
if ($key === null) $key = $name;
if ($header === null) $header = $name;
$definition["name"] = $name;
$definition["key"] = $key;
$definition["header"] = $header;
# autres éléments # autres éléments
self::ensure_nstring($definition["title"]); self::ensure_nstring($definition["title"]);
self::ensure_bool($definition["required"]); self::ensure_bool($definition["required"]);
@ -146,7 +155,7 @@ class ScalarSchema extends Schema {
self::ensure_ncallable($definition["normalizer_func"]); self::ensure_ncallable($definition["normalizer_func"]);
self::ensure_narray($definition["messages"]); self::ensure_narray($definition["messages"]);
self::ensure_ncallable($definition["formatter_func"]); self::ensure_ncallable($definition["formatter_func"]);
self::ensure_nkey($definition["name"]); self::ensure_nbool($definition["composite"]);
return $definition; return $definition;
} }
@ -156,7 +165,14 @@ class ScalarSchema extends Schema {
$this->definition = $definition; $this->definition = $definition;
} }
function isScalar(): bool { function isScalar(?ScalarSchema &$scalar=null): bool {
$scalar = $this;
return true; return true;
} }
function getValue(&$value, $key=null): IValue {
if ($value instanceof Input) $input = $value;
else $input = new Input($value);
return new ScalarValue($input, $this, $key);
}
} }

View File

@ -2,6 +2,7 @@
namespace nur\sery\schema; namespace nur\sery\schema;
use nulib\cl; use nulib\cl;
use nur\sery\schema\values\IValue;
abstract class Schema { abstract class Schema {
/** /**
@ -22,40 +23,52 @@ abstract class Schema {
return $md; return $md;
} }
protected static function ensure_nstring(&$string): void {
if ($string !== null && !is_string($string)) $string = strval($string);
}
protected static function ensure_string(&$string): void { protected static function ensure_string(&$string): void {
if (!is_string($string)) $string = strval($string); if (!is_string($string)) $string = strval($string);
} }
protected static function ensure_nbool(&$bool): void { protected static function ensure_nstring(&$string): void {
if ($bool !== null && !is_bool($bool)) $bool = boolval($bool); if ($string !== null) self::ensure_string($string);
} }
protected static function ensure_bool(&$bool): void { protected static function ensure_bool(&$bool): void {
if (!is_bool($bool)) $bool = boolval($bool); if (!is_bool($bool)) $bool = boolval($bool);
} }
protected static function ensure_nbool(&$bool): void {
if ($bool !== null) self::ensure_bool($bool);
}
protected static function ensure_callable(&$callable): void {
if (!is_callable($callable)) throw SchemaException::invalid_callable($callable);
}
protected static function ensure_ncallable(&$callable): void { protected static function ensure_ncallable(&$callable): void {
if ($callable !== null && !is_callable($callable)) { if ($callable !== null) self::ensure_callable($callable);
throw SchemaException::invalid_callable($callable);
}
}
protected static function ensure_narray(&$array): void {
if ($array !== null && !is_array($array)) $array = cl::with($array);
} }
protected static function ensure_array(&$array): void { protected static function ensure_array(&$array): void {
if (!is_array($array)) $array = cl::with($array); if (!is_array($array)) $array = cl::with($array);
} }
protected static function ensure_nkey(&$key): void { protected static function ensure_narray(&$array): void {
if ($key !== null && !is_string($key) && !is_int($key)) $key = strval($key); if ($array !== null) self::ensure_array($array);
} }
protected static function ensure_key(&$key): void { protected static function ensure_key(&$key): void {
if (!is_string($key) && !is_int($key)) $key = strval($key); if (!is_string($key) && !is_int($key)) $key = strval($key);
} }
protected static function ensure_ncontent(&$key): void { protected static function ensure_nkey(&$key): void {
if ($key !== null && !is_string($key) && !is_array($key)) $key = strval($key); if ($key !== null) self::ensure_key($key);
} }
protected static function ensure_content(&$key): void { protected static function ensure_pkey(&$pkey): void {
if (!is_string($key) && !is_array($key)) $key = strval($key); if (!is_string($pkey) && !is_int($pkey) && !is_array($pkey)) $pkey = strval($pkey);
if (is_array($pkey)) {
foreach ($pkey as &$key) {
self::ensure_key($key);
}; unset($key);
}
}
protected static function ensure_npkey(&$pkey): void {
if ($pkey !== null) self::ensure_pkey($pkey);
}
protected static function ensure_content(&$content): void {
if (!is_string($content) && !is_array($content)) $content = strval($content);
}
protected static function ensure_ncontent(&$content): void {
if ($content !== null) self::ensure_content($content);
} }
/** /**
@ -68,9 +81,11 @@ abstract class Schema {
protected $definition; protected $definition;
/** retourner true si le schéma est de nature tableau associatif */ /** retourner true si le schéma est de nature tableau associatif */
function isAssoc(): bool { return false; } function isAssoc(?AssocSchema &$assoc=null): bool { return false; }
/** retourner true si le schéma est de nature liste */ /** retourner true si le schéma est de nature liste */
function isList(): bool { return false; } function isList(?ListSchema &$list=null): bool { return false; }
/** retourner true si le schéma est de nature scalaire */ /** retourner true si le schéma est de nature scalaire */
function isScalar(): bool { return false; } function isScalar(?ScalarSchema &$scalar=null): bool { return false; }
abstract function getValue(&$value, $key=null): IValue;
} }

View File

@ -0,0 +1,22 @@
<?php
namespace nur\sery\schema\ref;
class ref_analyze {
/** @var int résultat de l'analyse: valeur inexistante */
const MISSING = 0;
/** @var int résultat de l'analyse: valeur nulle */
const NULL = 1;
/** @var int résultat de l'analyse: valeur chaine à parser */
const STRING = 2;
/** @var int résultat de l'analyse: valeur invalide */
const INVALID = 3;
/** @var int résultat de l'analyse: valeur valide mais pas normalisée */
const VALID = 4;
/** @var int résultat de l'analyse: valeur valide normalisée */
const NORMALIZED = 5;
}

View File

@ -34,7 +34,10 @@ class ref_schema {
"" => ["array", "scalar", "nature du schéma", "" => ["array", "scalar", "nature du schéma",
"" => ["assoc", "schema" => self::NATURE_METASCHEMA], "" => ["assoc", "schema" => self::NATURE_METASCHEMA],
], ],
"name" => ["?key", null, "identifiant de la valeur"], "name" => ["?string", null, "identifiant de la valeur"],
"key" => ["?pkey", null, "chemin de clé de la valeur dans un tableau associatif"],
"header" => ["?string", null, "nom de l'en-tête s'il faut présenter cette donnée dans un tableau"],
"composite" => ["?bool", null, "ce champ fait-il partie d'une valeur composite?"],
]; ];
const MESSAGES = [ const MESSAGES = [

View File

@ -4,6 +4,7 @@ namespace nur\sery\schema\ref;
class ref_types { class ref_types {
const ALIASES = [ const ALIASES = [
"key" => "string|int", "key" => "string|int",
"pkey" => "string|int|array",
"content" => "string|array", "content" => "string|array",
]; ];
} }

View File

@ -5,7 +5,7 @@ class AssocValue implements IValue {
use TValue; use TValue;
function isScalar(?ScalarValue &$scalar=null): bool { return false; } function isScalar(?ScalarValue &$scalar=null): bool { return false; }
function isSeq(?SeqValue &$seq=null): bool { return false; } function isList(?ListValue &$list=null): bool { return false; }
function isAssoc(?AssocValue &$assoc=null): bool { $assoc = $this; return true; } function isAssoc(?AssocValue &$assoc=null): bool { $assoc = $this; return true; }
function ensureKeys(): bool { function ensureKeys(): bool {

View File

@ -7,8 +7,8 @@ interface IValue {
/** retourner true si cette valeur est scalaire */ /** retourner true si cette valeur est scalaire */
function isScalar(?ScalarValue &$scalar=null): bool; function isScalar(?ScalarValue &$scalar=null): bool;
/** retourner true cette valeur est un tableau séquentiel */ /** retourner true cette valeur est une liste */
function isSeq(?SeqValue &$seq=null): bool; function isList(?ListValue &$list=null): bool;
/** retourner true cette valeur est un tableau associatif */ /** retourner true cette valeur est un tableau associatif */
function isAssoc(?AssocValue &$assoc=null): bool; function isAssoc(?AssocValue &$assoc=null): bool;

View File

@ -1,11 +1,11 @@
<?php <?php
namespace nur\sery\schema\values; namespace nur\sery\schema\values;
class SeqValue implements IValue { class ListValue implements IValue {
use TValue; use TValue;
function isScalar(?ScalarValue &$scalar=null): bool { return false; } function isScalar(?ScalarValue &$scalar=null): bool { return false; }
function isSeq(?SeqValue &$seq=null): bool { $seq = $this; return true; } function isList(?ListValue &$list=null): bool { $list = $this; return true; }
function isAssoc(?AssocValue &$assoc=null): bool { return false; } function isAssoc(?AssocValue &$assoc=null): bool { return false; }
function ensureKeys(): bool { function ensureKeys(): bool {

View File

@ -23,6 +23,7 @@ class Result {
$this->result = $result; $this->result = $result;
} }
/** @var array */
protected $result; protected $result;
function __get($name) { function __get($name) {

View File

@ -1,21 +1,26 @@
<?php <?php
namespace nur\sery\schema\values; namespace nur\sery\schema\values;
use nur\sery\schema\ScalarSchema;
use nur\sery\schema\types\IType; use nur\sery\schema\types\IType;
class ScalarValue implements IValue { class ScalarValue implements IValue {
use TValue; use TValue;
/** @var ?Result résultat de l'analyse de la valeur */ /** @var ScalarSchema schéma de cette valeur */
protected ?Result $result; protected $schema;
function __construct(&$value, array $schema, $key=null, bool $verifix=true) { /** @var ?Result résultat de l'analyse de la valeur */
protected $result;
function __construct(&$value, ScalarSchema $schema, $key=null, bool $verifix=true) {
$this->schema = $schema; $this->schema = $schema;
$this->reset($value, $key, $verifix); $this->reset($value, $key, $verifix);
#XXX résoudre les type dans reset()?
} }
function isScalar(?ScalarValue &$scalar=null): bool { $scalar = $this; return true; } function isScalar(?ScalarValue &$scalar=null): bool { $scalar = $this; return true; }
function isSeq(?SeqValue &$seq=null): bool { return false; } function isList(?ListValue &$list=null): bool { return false; }
function isAssoc(?AssocValue &$assoc=null): bool { return false; } function isAssoc(?AssocValue &$assoc=null): bool { return false; }
function get($default=null) { function get($default=null) {
@ -36,7 +41,7 @@ class ScalarValue implements IValue {
protected $type; protected $type;
function type(): IType { function type(): IType {
if ($this->type === null) $this->type = $this->md()->getType($this->key); if ($this->type === null) $this->type = $this->schema->getType($this->key);
return $this->type; return $this->type;
} }

View File

@ -4,16 +4,6 @@ namespace nur\sery\schema\values;
use nur\sery\schema\OldSchema; use nur\sery\schema\OldSchema;
trait TValue { trait TValue {
/** @var array schéma normalisé de cette valeur */
protected array $schema;
/** @var OldSchema */
protected OldSchema $md;
function md(): OldSchema {
return OldSchema::new($this->md, $this->schema, true);
}
/** @var mixed valeur ou référence d'un tableau contenant la valeur */ /** @var mixed valeur ou référence d'un tableau contenant la valeur */
protected $value; protected $value;

View File

@ -20,6 +20,9 @@ class ScalarSchemaTest extends TestCase {
"format" => null, "format" => null,
"" => ["scalar"], "" => ["scalar"],
"name" => null, "name" => null,
"key" => null,
"header" => null,
"composite" => null,
]; ];
static function schema(array $schema): array { static function schema(array $schema): array {