modifs.mineures sans commentaires
This commit is contained in:
parent
c5c4119e69
commit
bb5b30480e
@ -1,6 +1,5 @@
|
||||
# nulib\schema
|
||||
|
||||
* tester type===null --> implémenter traw et tmixed
|
||||
* ScalarSchema::from_property()
|
||||
|
||||
* dans AssocSchema, support `[key_prefix]` qui permet de spécifier un préfixe
|
||||
@ -32,38 +31,6 @@
|
||||
$wrapper->reset($value);
|
||||
# $value vaut ["x_a" => "5", "x_b" => 10];
|
||||
~~~
|
||||
* implémenter l'instanciation de types avec des paramètres particuliers. *si*
|
||||
des paramètres sont fournis, le type est instancié avec la signature
|
||||
`IType($typeDefinition, $schemaDefinition)` e.g
|
||||
~~~php
|
||||
const SCHEMA = ["type", default, "required" => true];
|
||||
# le type est instancié comme suit:
|
||||
$type = new ttype();
|
||||
|
||||
const SCHEMA = [[["type", ...]], default, "required" => true];
|
||||
// ou
|
||||
const SCHEMA = [["type" => [...]], default, "required" => true];
|
||||
# le type est instancié comme suit:
|
||||
# le tableau peut être une liste ou associatif, c'est au type de décider ce
|
||||
# qu'il en fait
|
||||
$type = new ttype(["type", ...], SCHEMA);
|
||||
~~~
|
||||
* ajouter à IType les méthodes getName() pour le nom officiel du type,
|
||||
getAliases() pour les alias supportés, et getClass() pour la définition de la
|
||||
classe dans les méthodes et propriétés
|
||||
getName() et getAliases() sont juste pour information, ils ne sont pas utilisés
|
||||
lors de la résolution du type effectif.
|
||||
* si cela a du sens, dans AssocSchema, n'instancier les schémas de chaque clé qu'à la demande.
|
||||
l'idée est de ne pas perdre du temps à instancier un schéma qui ne serait pas utilisé
|
||||
|
||||
on pourrait avoir d'une manière générale quelque chose comme:
|
||||
~~~
|
||||
Schema::ensure(&$schema, ?array $def=null, $defKey=null): Schema;
|
||||
~~~
|
||||
* si $schema est une instance de Schema, la retourner
|
||||
* si c'est un array, c'est une définition et il faut la remplacer par l'instance de Schema correspondant
|
||||
* sinon, prendre $def comme définition
|
||||
$key est la clé si $schema est dans un autre schema
|
||||
* actuellement, pour un schéma associatif, si on normalise un tableau séquentiel,
|
||||
chaque valeur correspond à la clé de même rang, eg. pour un schéma
|
||||
~~~php
|
||||
|
@ -115,6 +115,7 @@ class ScalarSchema extends Schema {
|
||||
$deftype = explode("|", $deftype);
|
||||
}
|
||||
foreach ($deftype as $type) {
|
||||
if ($type !== null) $type = trim($type);
|
||||
if ($type === null || $type === "null") {
|
||||
$nullable = true;
|
||||
continue;
|
||||
|
@ -6,8 +6,13 @@ use nur\sery\wip\schema\types\Registry;
|
||||
use nur\sery\wip\schema\types\tarray;
|
||||
use nur\sery\wip\schema\types\tbool;
|
||||
use nur\sery\wip\schema\types\tcallable;
|
||||
use nur\sery\wip\schema\types\tcontent;
|
||||
use nur\sery\wip\schema\types\tfloat;
|
||||
use nur\sery\wip\schema\types\tint;
|
||||
use nur\sery\wip\schema\types\tkey;
|
||||
use nur\sery\wip\schema\types\tmixed;
|
||||
use nur\sery\wip\schema\types\tpkey;
|
||||
use nur\sery\wip\schema\types\traw;
|
||||
use nur\sery\wip\schema\types\trawstring;
|
||||
use nur\sery\wip\schema\types\tstring;
|
||||
use nur\sery\wip\schema\types\ttext;
|
||||
@ -26,7 +31,7 @@ class types {
|
||||
return self::$registry;
|
||||
}
|
||||
|
||||
static function get(bool $nullable, string $name, ?array $params=null, ?array $definition=null): IType {
|
||||
static function get(bool $nullable, ?string $name, ?array $params=null, ?array $definition=null): IType {
|
||||
return self::registry()->get($nullable, $name, $params, $definition);
|
||||
}
|
||||
|
||||
@ -38,4 +43,9 @@ class types {
|
||||
static function float(bool $nullable=true): tfloat { return self::get($nullable, "float"); }
|
||||
static function array(bool $nullable=true): tarray { return self::get($nullable, "array"); }
|
||||
static function callable(bool $nullable=true): tcallable { return self::get($nullable, "callable"); }
|
||||
static function raw(bool $nullable=true): traw { return self::get($nullable, "raw"); }
|
||||
static function mixed(bool $nullable=true): tmixed { return self::get($nullable, "mixed"); }
|
||||
static function key(bool $nullable=true): tkey { return self::get($nullable, "key"); }
|
||||
static function pkey(bool $nullable=true): tpkey { return self::get($nullable, "pkey"); }
|
||||
static function content(bool $nullable=true): tcontent { return self::get($nullable, "content"); }
|
||||
}
|
||||
|
@ -10,6 +10,15 @@ use nur\sery\wip\schema\Schema;
|
||||
* Interface IType: un type de données
|
||||
*/
|
||||
interface IType {
|
||||
/**
|
||||
* obtenir, pour information, le nom officiel de ce type, utilisable dans une
|
||||
* définition de schéma
|
||||
*/
|
||||
function getName(): string;
|
||||
|
||||
/** obtenir la liste des aliases valides pour ce type */
|
||||
function getAliases(): array;
|
||||
|
||||
/**
|
||||
* @return string la classe des objets gérés par ce format: le type attendu
|
||||
* par {@link format()} et le type retourné par {@link verifix()}
|
||||
|
@ -16,6 +16,8 @@ class Registry {
|
||||
"array" => tarray::class,
|
||||
"callable" => tcallable::class,
|
||||
# types spéciaux
|
||||
"raw" => tmixed::class,
|
||||
"mixed" => tmixed::class,
|
||||
"key" => tkey::class,
|
||||
"pkey" => tpkey::class,
|
||||
"content" => tcontent::class,
|
||||
@ -28,7 +30,8 @@ class Registry {
|
||||
/** @var IType[] */
|
||||
protected $types;
|
||||
|
||||
function get(bool $nullable, string $name, ?array $params=null, ?array $definition=null): IType {
|
||||
function get(bool $nullable, ?string $name, ?array $params=null, ?array $definition=null): IType {
|
||||
$name ??= "raw";
|
||||
$class = self::TYPES[$name];
|
||||
$params = cl::merge($class::get_params_from_definition($definition), $params);
|
||||
if ($params !== null) {
|
||||
|
@ -7,6 +7,10 @@ use nur\sery\wip\schema\input\Input;
|
||||
use nur\str;
|
||||
|
||||
abstract class _tsimple implements IType {
|
||||
const NAME = null;
|
||||
|
||||
const ALIASES = [];
|
||||
|
||||
static function get_params_from_definition(?array $definition): ?array {
|
||||
return null;
|
||||
}
|
||||
@ -20,6 +24,14 @@ abstract class _tsimple implements IType {
|
||||
|
||||
protected ?array $params;
|
||||
|
||||
function getName(): string {
|
||||
return static::NAME;
|
||||
}
|
||||
|
||||
function getAliases(): array {
|
||||
return static::ALIASES;
|
||||
}
|
||||
|
||||
function getPhpType(bool $allowNullable=true): ?string {
|
||||
$phpType = $this->getClass();
|
||||
if ($phpType === "mixed") return null;
|
||||
@ -27,6 +39,10 @@ abstract class _tsimple implements IType {
|
||||
return $phpType;
|
||||
}
|
||||
|
||||
function is2States(): bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
function get2States(): array {
|
||||
throw StateException::not_implemented();
|
||||
}
|
||||
@ -51,10 +67,6 @@ abstract class _tsimple implements IType {
|
||||
return $value;
|
||||
}
|
||||
|
||||
function is2States(): bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
|
||||
function getGetterName(string $name): string {
|
||||
|
@ -9,6 +9,8 @@ use nur\sery\wip\schema\Result;
|
||||
use nur\sery\wip\schema\Schema;
|
||||
|
||||
class tarray extends _tstring {
|
||||
const NAME = "array";
|
||||
|
||||
const SPLIT_PATTERN = '/\s+/';
|
||||
const FORMAT = " ";
|
||||
|
||||
|
@ -11,6 +11,10 @@ use nur\sery\wip\schema\Result;
|
||||
use nur\sery\wip\schema\Schema;
|
||||
|
||||
class tbool extends _tformatable {
|
||||
const NAME = "bool";
|
||||
|
||||
const ALIASES = ["boolean"];
|
||||
|
||||
/** liste de valeurs chaines à considérer comme 'OUI' */
|
||||
const YES_VALUES = [
|
||||
"true", "vrai", "yes", "oui",
|
||||
|
@ -10,6 +10,10 @@ use nur\sery\wip\schema\Result;
|
||||
use nur\sery\wip\schema\Schema;
|
||||
|
||||
class tcallable extends _tsimple {
|
||||
const NAME = "callable";
|
||||
|
||||
const ALIASES = ["func", "function"];
|
||||
|
||||
static function ensure_callable(&$callable): void {
|
||||
$callable = func::ensure($callable);
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ use nur\sery\wip\schema\Result;
|
||||
use nur\sery\wip\schema\Schema;
|
||||
|
||||
abstract class tcontent extends _tunion {
|
||||
const NAME = "content";
|
||||
|
||||
static function ensure_content(&$content): void {
|
||||
if ($content === null || $content === false) $content = [];
|
||||
elseif (!is_string($content) && !is_array($content)) $content = strval($content);
|
||||
|
@ -8,6 +8,10 @@ use nur\sery\wip\schema\Result;
|
||||
use nur\sery\wip\schema\Schema;
|
||||
|
||||
class tfloat extends _tformatable {
|
||||
const NAME = "float";
|
||||
|
||||
const ALIASES = ["flt", "double", "dbl"];
|
||||
|
||||
static function ensure_float(&$float): void {
|
||||
if (!is_float($float)) $float = floatval($float);
|
||||
}
|
||||
|
@ -8,6 +8,10 @@ use nur\sery\wip\schema\Result;
|
||||
use nur\sery\wip\schema\Schema;
|
||||
|
||||
class tint extends _tformatable {
|
||||
const NAME = "int";
|
||||
|
||||
const ALIASES = ["integer"];
|
||||
|
||||
static function ensure_int(&$int): void {
|
||||
if (!is_int($int)) $int = intval($int);
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ use nur\sery\wip\schema\Result;
|
||||
use nur\sery\wip\schema\Schema;
|
||||
|
||||
class tkey extends _tunion {
|
||||
const NAME = "key";
|
||||
|
||||
static function ensure_key(&$key): void {
|
||||
if ($key === null) $key = "";
|
||||
elseif ($key === false) $key = 0;
|
||||
|
46
src/schema/types/tmixed.php
Normal file
46
src/schema/types/tmixed.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace nur\sery\wip\schema\types;
|
||||
|
||||
use nur\sery\wip\schema\_scalar\ScalarResult;
|
||||
use nur\sery\wip\schema\_scalar\ScalarSchema;
|
||||
use nur\sery\wip\schema\input\Input;
|
||||
use nur\sery\wip\schema\Result;
|
||||
use nur\sery\wip\schema\Schema;
|
||||
|
||||
class tmixed extends _tsimple {
|
||||
const NAME = "mixed";
|
||||
|
||||
function getClass(): string {
|
||||
return "mixed";
|
||||
}
|
||||
|
||||
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 true;
|
||||
}
|
||||
|
||||
function parse(string $value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 var_export($value, true);
|
||||
}
|
||||
}
|
@ -7,6 +7,8 @@ use nur\sery\wip\schema\Result;
|
||||
use nur\sery\wip\schema\Schema;
|
||||
|
||||
class tpkey extends _tunion {
|
||||
const NAME = "pkey";
|
||||
|
||||
static function ensure_pkey(&$pkey): void {
|
||||
if ($pkey === null) $pkey = "";
|
||||
elseif ($pkey === false) $pkey = 0;
|
||||
|
16
src/schema/types/traw.php
Normal file
16
src/schema/types/traw.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace nur\sery\wip\schema\types;
|
||||
|
||||
use nur\sery\wip\schema\input\Input;
|
||||
|
||||
class traw extends tmixed {
|
||||
const NAME = "raw";
|
||||
|
||||
function isAvailable(Input $input, $valueKey): bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isNull($value): bool {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -8,6 +8,8 @@ use nur\sery\wip\schema\Result;
|
||||
use nur\sery\wip\schema\Schema;
|
||||
|
||||
class trawstring extends _tstring {
|
||||
const NAME = "rawstring";
|
||||
|
||||
static function ensure_string(&$string): void {
|
||||
if (!is_string($string)) $string = strval($string);
|
||||
if (static::TRIM) $string = trim($string);
|
||||
|
@ -2,5 +2,7 @@
|
||||
namespace nur\sery\wip\schema\types;
|
||||
|
||||
class tstring extends trawstring {
|
||||
const NAME = "string";
|
||||
|
||||
const TRIM = true;
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
namespace nur\sery\wip\schema\types;
|
||||
|
||||
class ttext extends trawstring {
|
||||
const NAME = "text";
|
||||
|
||||
const TRIM = true;
|
||||
const NORM_NL = true;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ namespace nur\sery\wip\schema\_scalar;
|
||||
use nulib\tests\TestCase;
|
||||
use nulib\ValueException;
|
||||
use nur\sery\wip\schema\input\Input;
|
||||
use stdClass;
|
||||
|
||||
class ScalarValueTest extends TestCase {
|
||||
function checkValue(ScalarWrapper $wrapper, $dest, bool $present, bool $available, bool $valid, bool $normalized): void {
|
||||
@ -30,6 +31,58 @@ class ScalarValueTest extends TestCase {
|
||||
});
|
||||
}
|
||||
|
||||
function testRaw() {
|
||||
$schema = new ScalarSchema();
|
||||
|
||||
$this->checkVerifix($schema, false, false, false, true, true, true, true);
|
||||
$this->checkVerifix($schema, false, true, false, true, true, true, true);
|
||||
|
||||
$this->checkVerifix($schema, null, false, null, true, true, true, true);
|
||||
$this->checkVerifix($schema, null, true, null, true, true, true, true);
|
||||
|
||||
$obj = new stdClass();
|
||||
$this->checkVerifix($schema, $obj, false, $obj, true, true, true, true);
|
||||
$this->checkVerifix($schema, $obj, true, $obj, true, true, true, true);
|
||||
|
||||
$schema = new ScalarSchema("raw");
|
||||
|
||||
$this->checkVerifix($schema, false, false, false, true, true, true, true);
|
||||
$this->checkVerifix($schema, false, true, false, true, true, true, true);
|
||||
|
||||
$this->checkVerifix($schema, null, false, null, true, true, true, true);
|
||||
$this->checkVerifix($schema, null, true, null, true, true, true, true);
|
||||
|
||||
$obj = new stdClass();
|
||||
$this->checkVerifix($schema, $obj, false, $obj, true, true, true, true);
|
||||
$this->checkVerifix($schema, $obj, true, $obj, true, true, true, true);
|
||||
}
|
||||
|
||||
function testMixed() {
|
||||
$schema = new ScalarSchema("mixed");
|
||||
|
||||
$this->checkVerifix($schema, false, false, false, true, true, true, true);
|
||||
$this->checkVerifix($schema, false, true, false, true, true, true, true);
|
||||
|
||||
$this->checkVerifix($schema, null, false, null, true, true, false, false);
|
||||
$this->checkException($schema, null, true, ValueException::class);
|
||||
|
||||
$obj = new stdClass();
|
||||
$this->checkVerifix($schema, $obj, false, $obj, true, true, true, true);
|
||||
$this->checkVerifix($schema, $obj, true, $obj, true, true, true, true);
|
||||
|
||||
$schema = new ScalarSchema("?mixed");
|
||||
|
||||
$this->checkVerifix($schema, false, false, false, true, true, true, true);
|
||||
$this->checkVerifix($schema, false, true, false, true, true, true, true);
|
||||
|
||||
$this->checkVerifix($schema, null, false, null, true, true, true, true);
|
||||
$this->checkVerifix($schema, null, true, null, true, true, true, true);
|
||||
|
||||
$obj = new stdClass();
|
||||
$this->checkVerifix($schema, $obj, false, $obj, true, true, true, true);
|
||||
$this->checkVerifix($schema, $obj, true, $obj, true, true, true, true);
|
||||
}
|
||||
|
||||
function testRawstring() {
|
||||
$schema = new ScalarSchema("rawstring");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user