modifs.mineures sans commentaires
This commit is contained in:
parent
ea1b774d0f
commit
3028fe12f7
1
TODO.md
1
TODO.md
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
## schema
|
## schema
|
||||||
|
|
||||||
* [ ] properties dans ScalarSchema, avec aliases pour notamment "nature" => ""
|
|
||||||
* [ ] remplacer IValue et TValue par une classe abstraite Value
|
* [ ] 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
|
-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\schema\values;
|
namespace nur\sery\schema;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Result: résultat de l'analyse ou de la normalisation d'une valeur
|
* Class Result: résultat de l'analyse ou de la normalisation d'une valeur
|
|
@ -2,28 +2,29 @@
|
||||||
namespace nur\sery\schema;
|
namespace nur\sery\schema;
|
||||||
|
|
||||||
use ArrayAccess;
|
use ArrayAccess;
|
||||||
use BadMethodCallException;
|
|
||||||
use LogicException;
|
use LogicException;
|
||||||
use nulib\cl;
|
use nulib\cl;
|
||||||
use nur\sery\schema\values\IValue;
|
use nur\sery\schema\schemas\AssocSchema;
|
||||||
|
use nur\sery\schema\schemas\ListSchema;
|
||||||
|
use nur\sery\schema\schemas\ScalarSchema;
|
||||||
|
|
||||||
abstract class Schema implements ArrayAccess {
|
abstract class Schema implements ArrayAccess {
|
||||||
/**
|
/**
|
||||||
* créer si besoin une nouvelle instance à partir d'une définition de schéma
|
* créer si besoin une nouvelle instance à partir d'une définition de schéma
|
||||||
*/
|
*/
|
||||||
static function new(&$md, $definition): self {
|
static function ns(?Schema &$schema, $definition): self {
|
||||||
if ($md === null) {
|
if ($schema === null) {
|
||||||
if (AssocSchema::isa_definition($definition)) {
|
if (AssocSchema::isa_definition($definition)) {
|
||||||
$md = new AssocSchema($definition);
|
$schema = new AssocSchema($definition);
|
||||||
} elseif (ListSchema::isa_definition($definition)) {
|
} elseif (ListSchema::isa_definition($definition)) {
|
||||||
$md = new ListSchema($definition);
|
$schema = new ListSchema($definition);
|
||||||
} elseif (ScalarSchema::isa_definition($definition)) {
|
} elseif (ScalarSchema::isa_definition($definition)) {
|
||||||
$md = new ScalarSchema($definition);
|
$schema = new ScalarSchema($definition);
|
||||||
} else {
|
} else {
|
||||||
throw SchemaException::invalid_schema();
|
throw SchemaException::invalid_schema();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $md;
|
return $schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,8 +43,11 @@ abstract class Schema implements ArrayAccess {
|
||||||
/** retourner true si le schéma est de nature scalaire */
|
/** retourner true si le schéma est de nature scalaire */
|
||||||
function isScalar(?ScalarSchema &$scalar=null): bool { return false; }
|
function isScalar(?ScalarSchema &$scalar=null): bool { return false; }
|
||||||
|
|
||||||
abstract function getValue(&$value, $key=null): IValue;
|
/**
|
||||||
|
* Créer si besoin une nouvelle instance de {@link Value} qui référence la
|
||||||
|
* variable $dest
|
||||||
|
*/
|
||||||
|
abstract function nv(?Value &$value=null, &$dest=null, $key=null): Value;
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
# key & properties
|
# key & properties
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
namespace nur\sery\schema;
|
||||||
|
|
||||||
|
use nur\sery\schema\types\IType;
|
||||||
|
use nur\sery\schema\values\AssocValue;
|
||||||
|
use nur\sery\schema\values\ListValue;
|
||||||
|
use nur\sery\schema\values\ScalarValue;
|
||||||
|
|
||||||
|
abstract class Value {
|
||||||
|
function isAssoc(?AssocValue &$assoc=null): bool { return false; }
|
||||||
|
function isList(?ListValue &$list=null): bool { return false; }
|
||||||
|
function isScalar(?ScalarValue &$scalar=null): bool { return false; }
|
||||||
|
|
||||||
|
abstract function reset(&$dest, $key=null, bool $verifix=true): self;
|
||||||
|
|
||||||
|
/** retourner le type associé à cette valeur */
|
||||||
|
abstract function getType(): IType;
|
||||||
|
|
||||||
|
/** retourner true si la valeur existe */
|
||||||
|
abstract function exists(): bool;
|
||||||
|
|
||||||
|
/** retourner true si la valeur est valide */
|
||||||
|
abstract function valid(): bool;
|
||||||
|
|
||||||
|
/** retourner true si la valeur est dans sa forme normalisée */
|
||||||
|
abstract function normalized(): bool;
|
||||||
|
}
|
|
@ -1,32 +1,36 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\schema\input;
|
namespace nur\sery\schema\input;
|
||||||
|
|
||||||
|
#XXX available permet de préciser qu'une valeur doit exister et être non vide
|
||||||
|
# pour être considérée. en faire un paramètre, à moins que ce soit au niveau du
|
||||||
|
# type qu'il faille le gérer?
|
||||||
/**
|
/**
|
||||||
* Class Input: accès à une valeur
|
* Class Input: accès à une valeur
|
||||||
*
|
*
|
||||||
* cette implémentation lit depuis et écrit dans une référence
|
* cette implémentation lit depuis et écrit dans une référence
|
||||||
*/
|
*/
|
||||||
class Input {
|
class Input {
|
||||||
function __construct(&$value=null) {
|
function __construct(&$dest=null) {
|
||||||
$this->value =& $value;
|
$this->dest =& $dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $value;
|
protected $dest;
|
||||||
|
|
||||||
|
/** tester si la valeur existe */
|
||||||
function exists($key=null): bool {
|
function exists($key=null): bool {
|
||||||
if ($key === null) return true;
|
if ($key === null) return true;
|
||||||
return $this->value !== null && array_key_exists($key, $this->value);
|
return $this->dest !== null && array_key_exists($key, $this->dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get($key=null) {
|
function get($key=null) {
|
||||||
if ($key === null) return $this->value;
|
if ($key === null) return $this->dest;
|
||||||
elseif ($this->value === null) return null;
|
elseif ($this->dest === null) return null;
|
||||||
elseif (!array_key_exists($key, $this->value)) return null;
|
elseif (!array_key_exists($key, $this->dest)) return null;
|
||||||
else return $this->value[$key];
|
else return $this->dest[$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
function set($value, $key=null): void {
|
function set($value, $key=null): void {
|
||||||
if ($key === null) $this->value = $value;
|
if ($key === null) $this->dest = $value;
|
||||||
else $this->value[$key] = $value;
|
else $this->dest[$key] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\schema;
|
namespace nur\sery\schema\schemas;
|
||||||
|
|
||||||
use nulib\cl;
|
use nulib\cl;
|
||||||
|
use nur\sery\schema\input\Input;
|
||||||
|
use nur\sery\schema\Schema;
|
||||||
|
use nur\sery\schema\Value;
|
||||||
|
use nur\sery\schema\values\AssocValue;
|
||||||
|
use nur\sery\schema\values\ScalarValue;
|
||||||
|
|
||||||
class AssocSchema extends Schema {
|
class AssocSchema extends Schema {
|
||||||
/** @var array meta-schema d'un schéma de nature tableau associatif */
|
/** @var array meta-schema d'un schéma de nature tableau associatif */
|
||||||
|
@ -29,7 +34,6 @@ class AssocSchema extends Schema {
|
||||||
}
|
}
|
||||||
|
|
||||||
static function normalize($definition): array {
|
static function normalize($definition): array {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function __construct($definition=null, bool $normalize=true) {
|
function __construct($definition=null, bool $normalize=true) {
|
||||||
|
@ -42,4 +46,11 @@ class AssocSchema extends Schema {
|
||||||
$assoc = $this;
|
$assoc = $this;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function nv(?Value &$value=null, &$dest=null, $key=null): Value {
|
||||||
|
if (!($value instanceof AssocValue)) $value = new AssocValue($this);
|
||||||
|
if ($dest instanceof Input) $input = $dest;
|
||||||
|
else $input = new Input($dest);
|
||||||
|
return $value->reset($input, $key);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\schema;
|
namespace nur\sery\schema\schemas;
|
||||||
|
|
||||||
|
use nur\sery\schema\input\Input;
|
||||||
|
use nur\sery\schema\Schema;
|
||||||
|
use nur\sery\schema\Value;
|
||||||
|
use nur\sery\schema\values\ListValue;
|
||||||
|
|
||||||
class ListSchema extends Schema {
|
class ListSchema extends Schema {
|
||||||
/** @var array meta-schema d'un schéma de nature liste */
|
/** @var array meta-schema d'un schéma de nature liste */
|
||||||
|
@ -29,7 +34,6 @@ class ListSchema extends Schema {
|
||||||
}
|
}
|
||||||
|
|
||||||
static function normalize($definition): array {
|
static function normalize($definition): array {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function __construct($definition=null, bool $normalize=true) {
|
function __construct($definition=null, bool $normalize=true) {
|
||||||
|
@ -42,4 +46,11 @@ class ListSchema extends Schema {
|
||||||
$list = $this;
|
$list = $this;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function nv(?Value &$value=null, &$dest=null, $key=null): Value {
|
||||||
|
if (!($value instanceof ListValue)) $value = new ListValue($this);
|
||||||
|
if ($dest instanceof Input) $input = $dest;
|
||||||
|
else $input = new Input($dest);
|
||||||
|
return $value->reset($input, $key);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,17 +1,19 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\schema;
|
namespace nur\sery\schema\schemas;
|
||||||
|
|
||||||
use nulib\cl;
|
use nulib\cl;
|
||||||
use nur\sery\schema\input\Input;
|
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\Schema;
|
||||||
|
use nur\sery\schema\SchemaException;
|
||||||
use nur\sery\schema\types\tarray;
|
use nur\sery\schema\types\tarray;
|
||||||
use nur\sery\schema\types\tbool;
|
use nur\sery\schema\types\tbool;
|
||||||
use nur\sery\schema\types\tcallable;
|
use nur\sery\schema\types\tcallable;
|
||||||
use nur\sery\schema\types\tcontent;
|
use nur\sery\schema\types\tcontent;
|
||||||
use nur\sery\schema\types\tpkey;
|
use nur\sery\schema\types\tpkey;
|
||||||
use nur\sery\schema\types\tstring;
|
use nur\sery\schema\types\tstring;
|
||||||
use nur\sery\schema\values\IValue;
|
use nur\sery\schema\Value;
|
||||||
use nur\sery\schema\values\ScalarValue;
|
use nur\sery\schema\values\ScalarValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -180,10 +182,9 @@ class ScalarSchema extends Schema {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getValue(&$value, $key=null): IValue {
|
function nv(?Value &$value=null, &$dest=null, $key=null): Value {
|
||||||
if ($value instanceof Input) $input = $value;
|
if (!($value instanceof ScalarValue)) $value = new ScalarValue($this);
|
||||||
else $input = new Input($value);
|
return $value->reset($dest, $key);
|
||||||
return new ScalarValue($input, $this, $key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
namespace nur\sery\schema;
|
||||||
|
|
||||||
|
use nur\sery\schema\types\IType;
|
||||||
|
use nur\sery\schema\types\Registry;
|
||||||
|
use nur\sery\schema\types\tarray;
|
||||||
|
use nur\sery\schema\types\tbool;
|
||||||
|
use nur\sery\schema\types\tcallable;
|
||||||
|
use nur\sery\schema\types\tfloat;
|
||||||
|
use nur\sery\schema\types\tint;
|
||||||
|
use nur\sery\schema\types\tstring;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class types: classe outil pour gérer le registre de types
|
||||||
|
*/
|
||||||
|
class types {
|
||||||
|
/** @var Registry */
|
||||||
|
private static $registry;
|
||||||
|
|
||||||
|
static function registry(): Registry {
|
||||||
|
if (self::$registry === null) {
|
||||||
|
self::$registry = new Registry();
|
||||||
|
}
|
||||||
|
return self::$registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function get(string $name): IType {
|
||||||
|
return self::registry()->get($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function string(): tstring { return self::get("string"); }
|
||||||
|
static function bool(): tbool { return self::get("bool"); }
|
||||||
|
static function int(): tint { return self::get("int"); }
|
||||||
|
static function float(): tfloat { return self::get("float"); }
|
||||||
|
static function array(): tarray { return self::get("array"); }
|
||||||
|
static function callable(): tcallable { return self::get("callable"); }
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\schema\types;
|
namespace nur\sery\schema\types;
|
||||||
|
|
||||||
use nur\sery\schema\values\Result;
|
use nur\sery\schema\Result;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface IType: un type de données
|
* Interface IType: un type de données
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
namespace nur\sery\schema\types;
|
||||||
|
|
||||||
|
class Registry {
|
||||||
|
const TYPES = [
|
||||||
|
"string" => tstring::class,
|
||||||
|
"bool" => tbool::class, "boolean" => tbool::class,
|
||||||
|
"int" => tint::class, "integer" => tint::class,
|
||||||
|
"float" => tfloat::class, "flt" => tfloat::class,
|
||||||
|
"double" => tfloat::class, "dbl" => tfloat::class,
|
||||||
|
"array" => tarray::class,
|
||||||
|
"callable" => tcallable::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
function __construct() {
|
||||||
|
$this->types = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var IType[] */
|
||||||
|
protected $types;
|
||||||
|
|
||||||
|
function get(string $name): IType {
|
||||||
|
#XXX les instancier
|
||||||
|
return $this->types[$name];
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ namespace nur\sery\schema\types;
|
||||||
|
|
||||||
use nulib\cl;
|
use nulib\cl;
|
||||||
|
|
||||||
class tarray {
|
class tarray implements IType {
|
||||||
static function ensure_array(&$array): void {
|
static function ensure_array(&$array): void {
|
||||||
if (!is_array($array)) $array = cl::with($array);
|
if (!is_array($array)) $array = cl::with($array);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\schema\types;
|
namespace nur\sery\schema\types;
|
||||||
|
|
||||||
class tbool {
|
class tbool implements IType {
|
||||||
static function ensure_bool(&$bool): void {
|
static function ensure_bool(&$bool): void {
|
||||||
if (!is_bool($bool)) $bool = boolval($bool);
|
if (!is_bool($bool)) $bool = boolval($bool);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ namespace nur\sery\schema\types;
|
||||||
|
|
||||||
use nur\sery\schema\SchemaException;
|
use nur\sery\schema\SchemaException;
|
||||||
|
|
||||||
class tcallable {
|
class tcallable implements IType {
|
||||||
static function ensure_callable(&$callable): void {
|
static function ensure_callable(&$callable): void {
|
||||||
if (!is_callable($callable)) throw SchemaException::invalid_callable($callable);
|
if (!is_callable($callable)) throw SchemaException::invalid_callable($callable);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\schema\types;
|
namespace nur\sery\schema\types;
|
||||||
|
|
||||||
class tcontent {
|
class tcontent implements IType {
|
||||||
static function ensure_content(&$content): void {
|
static function ensure_content(&$content): void {
|
||||||
if (!is_string($content) && !is_array($content)) $content = strval($content);
|
if (!is_string($content) && !is_array($content)) $content = strval($content);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
namespace nur\sery\schema\types;
|
||||||
|
|
||||||
|
class tfloat implements IType {
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
namespace nur\sery\schema\types;
|
||||||
|
|
||||||
|
class tint implements IType {
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\schema\types;
|
namespace nur\sery\schema\types;
|
||||||
|
|
||||||
class tkey {
|
class tkey implements IType {
|
||||||
static function ensure_key(&$key): void {
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\schema\types;
|
namespace nur\sery\schema\types;
|
||||||
|
|
||||||
class tpkey {
|
class tpkey implements IType {
|
||||||
static function ensure_pkey(&$pkey): void {
|
static function ensure_pkey(&$pkey): void {
|
||||||
if (!is_string($pkey) && !is_int($pkey) && !is_array($pkey)) $pkey = strval($pkey);
|
if (!is_string($pkey) && !is_int($pkey) && !is_array($pkey)) $pkey = strval($pkey);
|
||||||
if (is_array($pkey)) {
|
if (is_array($pkey)) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\schema\types;
|
namespace nur\sery\schema\types;
|
||||||
|
|
||||||
class tstring {
|
class tstring implements IType {
|
||||||
static function ensure_string(&$string): void {
|
static function ensure_string(&$string): void {
|
||||||
if (!is_string($string)) $string = strval($string);
|
if (!is_string($string)) $string = strval($string);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\schema\values;
|
namespace nur\sery\schema\values;
|
||||||
|
|
||||||
class AssocValue implements IValue {
|
use nur\sery\schema\Value;
|
||||||
use TValue;
|
use nur\sery\schema\Result;
|
||||||
|
|
||||||
function isScalar(?ScalarValue &$scalar=null): bool { return false; }
|
class AssocValue extends Value {
|
||||||
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 {
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace nur\sery\schema\values;
|
|
||||||
|
|
||||||
use nur\sery\schema\types\IType;
|
|
||||||
|
|
||||||
interface IValue {
|
|
||||||
/** retourner true si cette valeur est scalaire */
|
|
||||||
function isScalar(?ScalarValue &$scalar=null): bool;
|
|
||||||
|
|
||||||
/** retourner true cette valeur est une liste */
|
|
||||||
function isList(?ListValue &$list=null): bool;
|
|
||||||
|
|
||||||
/** retourner true cette valeur est un tableau associatif */
|
|
||||||
function isAssoc(?AssocValue &$assoc=null): bool;
|
|
||||||
|
|
||||||
function reset(&$value, $key=null, bool $verifix=true): void;
|
|
||||||
|
|
||||||
/** retourner true si la valeur existe */
|
|
||||||
function exists(): bool;
|
|
||||||
|
|
||||||
/** retourner true si la valeur est valide */
|
|
||||||
function isValid(): bool;
|
|
||||||
|
|
||||||
/** retourner true si la valeur est dans sa forme normalisée */
|
|
||||||
function isNormalized();
|
|
||||||
|
|
||||||
/** retourner le type associé à cette valeur */
|
|
||||||
function getType(): IType;
|
|
||||||
}
|
|
|
@ -1,12 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\schema\values;
|
namespace nur\sery\schema\values;
|
||||||
|
|
||||||
class ListValue implements IValue {
|
use nur\sery\schema\Result;
|
||||||
use TValue;
|
use nur\sery\schema\Value;
|
||||||
|
|
||||||
function isScalar(?ScalarValue &$scalar=null): bool { return false; }
|
class ListValue extends Value {
|
||||||
function isList(?ListValue &$list=null): bool { $list = $this; return true; }
|
function isList(?ListValue &$list=null): bool { $list = $this; return true; }
|
||||||
function isAssoc(?AssocValue &$assoc=null): bool { return false; }
|
|
||||||
|
|
||||||
function ensureKeys(): bool {
|
function ensureKeys(): bool {
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,52 +1,71 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\schema\values;
|
namespace nur\sery\schema\values;
|
||||||
|
|
||||||
use nur\sery\schema\ScalarSchema;
|
use nur\sery\schema\input\Input;
|
||||||
|
use nur\sery\schema\Result;
|
||||||
|
use nur\sery\schema\schemas\ScalarSchema;
|
||||||
use nur\sery\schema\types\IType;
|
use nur\sery\schema\types\IType;
|
||||||
|
use nur\sery\schema\Value;
|
||||||
|
|
||||||
class ScalarValue implements IValue {
|
class ScalarValue extends Value {
|
||||||
use TValue;
|
function __construct(ScalarSchema $schema, &$dest=null, $key=null, bool $verifix=true) {
|
||||||
|
$this->schema = $schema;
|
||||||
|
$this->reset($dest, $key, $verifix);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isScalar(?ScalarValue &$scalar=null): bool { $scalar = $this; return true; }
|
||||||
|
|
||||||
/** @var ScalarSchema schéma de cette valeur */
|
/** @var ScalarSchema schéma de cette valeur */
|
||||||
protected $schema;
|
protected $schema;
|
||||||
|
|
||||||
|
/** @var Input source et destination de la valeur */
|
||||||
|
protected $input;
|
||||||
|
|
||||||
|
/** @var string|int clé de la valeur dans le tableau destination */
|
||||||
|
protected $key;
|
||||||
|
|
||||||
/** @var ?Result résultat de l'analyse de la valeur */
|
/** @var ?Result résultat de l'analyse de la valeur */
|
||||||
protected $result;
|
protected $result;
|
||||||
|
|
||||||
function __construct(&$value, ScalarSchema $schema, $key=null, bool $verifix=true) {
|
function reset(&$dest, $key=null, bool $verifix=true): Value {
|
||||||
$this->schema = $schema;
|
if ($dest instanceof Input) $input = $dest;
|
||||||
$this->reset($value, $key, $verifix);
|
else $input = new Input($dest);
|
||||||
#XXX résoudre les type dans reset()?
|
$this->input = $input;
|
||||||
|
$this->key = $key;
|
||||||
|
$this->result = null;
|
||||||
|
#XXX résoudre les types ici?
|
||||||
|
if ($verifix) $this->verifix();
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isScalar(?ScalarValue &$scalar=null): bool { $scalar = $this; return true; }
|
function exists(): bool {
|
||||||
function isList(?ListValue &$list=null): bool { return false; }
|
return $this->input->exists($this->key);
|
||||||
function isAssoc(?AssocValue &$assoc=null): bool { return false; }
|
}
|
||||||
|
|
||||||
function get($default=null) {
|
function get($default=null) {
|
||||||
$key = $this->key;
|
$key = $this->key;
|
||||||
if ($key === null) return $this->value;
|
$input = $this->input;
|
||||||
elseif (array_key_exists($key, $this->value)) return $this->value[$key];
|
if ($input->exists($key)) return $input->get($key);
|
||||||
else return $default;
|
else return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
function set($value): self {
|
function set($value): self {
|
||||||
$key = $this->key;
|
$this->input->set($value, $this->key);
|
||||||
if ($key === null) $this->value = $value;
|
|
||||||
else $this->value[$key] = $value;
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var IType */
|
/** @var IType */
|
||||||
protected $type;
|
protected $type;
|
||||||
|
|
||||||
function type(): IType {
|
function getType(): IType {
|
||||||
if ($this->type === null) $this->type = $this->schema->getType($this->key);
|
if ($this->type === null) $this->type = $this->schema->getType($this->key);
|
||||||
return $this->type;
|
return $this->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
function exists(): bool {
|
function valid(): bool {
|
||||||
return $this->type()->exists($this->value, $this->key);
|
}
|
||||||
|
|
||||||
|
function normalized(): bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,25 +74,25 @@ class ScalarValue implements IValue {
|
||||||
* si la valeur était déjà normalisée, retourner false.
|
* si la valeur était déjà normalisée, retourner false.
|
||||||
*/
|
*/
|
||||||
function verifix(bool $throw=true, ?Result &$result=null): bool {
|
function verifix(bool $throw=true, ?Result &$result=null): bool {
|
||||||
$type = $this->type();
|
$type = $this->getType();
|
||||||
$key = $this->key;
|
$key = $this->key;
|
||||||
if ($key === null) $modified = $type->verifix($this->value, $throw, $result);
|
if ($key === null) $modified = $type->verifix($this->input, $throw, $result);
|
||||||
else $modified = $type->verifix($this->value[$key], $throw, $result);
|
else $modified = $type->verifix($this->input[$key], $throw, $result);
|
||||||
$this->result = $result;
|
$this->result = $result;
|
||||||
return $modified;
|
return $modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse($value, bool $throw=true, ?Result &$result=null) {
|
function parse($value, bool $throw=true, ?Result &$result=null) {
|
||||||
$this->type()->verifix($value, $throw, $result);
|
$this->getType()->verifix($value, $throw, $result);
|
||||||
$this->set($value);
|
$this->set($value);
|
||||||
$this->result = $result;
|
$this->result = $result;
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function format(?string $format=null): string {
|
function format(?string $format=null): string {
|
||||||
$type = $this->type();
|
$type = $this->getType();
|
||||||
$key = $this->key;
|
$key = $this->key;
|
||||||
if ($key === null) return $type->format($this->value, $format);
|
if ($key === null) return $type->format($this->input, $format);
|
||||||
else return $type->format($this->value[$key], $format);
|
else return $type->format($this->input[$key], $format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace nur\sery\schema\values;
|
|
||||||
|
|
||||||
trait TValue {
|
|
||||||
/** @var mixed valeur ou référence d'un tableau contenant la valeur */
|
|
||||||
protected $value;
|
|
||||||
|
|
||||||
/** @var string|int clé de la valeur dans le tableau destination */
|
|
||||||
protected $key;
|
|
||||||
|
|
||||||
function reset(&$value, $key=null, bool $verifix=true): void {
|
|
||||||
$this->value =& $value;
|
|
||||||
$this->key = $key;
|
|
||||||
$this->result = null;
|
|
||||||
if ($verifix) $this->verifix();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
<?php
|
||||||
|
namespace nur\sery\schema;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use nulib\tests\TestCase;
|
||||||
|
use nur\sery\schema\values\ScalarValue;
|
||||||
|
|
||||||
|
class schemaTest extends TestCase {
|
||||||
|
function testInt() {
|
||||||
|
Schema::ns($schema, "int");
|
||||||
|
/** @var ScalarValue $intv */
|
||||||
|
$schema->nv($intv, $int);
|
||||||
|
$f = function($value) use($intv) {
|
||||||
|
return function() use($intv, $value) {
|
||||||
|
$intv->set($value);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
self::assertException(Exception::class, $f(null));
|
||||||
|
self::assertException(Exception::class, $f(""));
|
||||||
|
self::assertException(Exception::class, $f(" "));
|
||||||
|
|
||||||
|
$intv->set(12);
|
||||||
|
self::assertSame(12, $intv->get());
|
||||||
|
self::assertSame(12, $int);
|
||||||
|
self::assertSame("12", $intv->format());
|
||||||
|
self::assertSame("0012", $intv->format("%4u"));
|
||||||
|
|
||||||
|
$intv->set("12");
|
||||||
|
self::assertSame(12, $intv->get());
|
||||||
|
|
||||||
|
$intv->set(" 12 ");
|
||||||
|
self::assertSame(12, $intv->get());
|
||||||
|
|
||||||
|
self::assertException(Exception::class, $f(true));
|
||||||
|
self::assertException(Exception::class, $f(false));
|
||||||
|
self::assertException(Exception::class, $f("a"));
|
||||||
|
self::assertException(Exception::class, $f([]));
|
||||||
|
self::assertException(Exception::class, $f(["a"]));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testNint() {
|
||||||
|
Schema::ns($schema, ["?int"]);
|
||||||
|
/** @var ScalarValue $intv */
|
||||||
|
$schema->nv($intv, $int);
|
||||||
|
$f = function($value) use($intv) {
|
||||||
|
return function() use($intv, $value) {
|
||||||
|
$intv->set($value);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
$intv->set(null);
|
||||||
|
self::assertNull($intv->get());
|
||||||
|
self::assertNull($int);
|
||||||
|
self::assertSame("", $intv->format());
|
||||||
|
|
||||||
|
$intv->set("");
|
||||||
|
self::assertNull($intv->get());
|
||||||
|
self::assertNull($int);
|
||||||
|
self::assertSame("", $intv->format());
|
||||||
|
|
||||||
|
$intv->set(" ");
|
||||||
|
self::assertNull($intv->get());
|
||||||
|
self::assertNull($int);
|
||||||
|
self::assertSame("", $intv->format());
|
||||||
|
|
||||||
|
$intv->set(12);
|
||||||
|
self::assertSame(12, $intv->get());
|
||||||
|
self::assertSame(12, $int);
|
||||||
|
self::assertSame("12", $intv->format());
|
||||||
|
self::assertSame("0012", $intv->format("%4u"));
|
||||||
|
|
||||||
|
$intv->set("12");
|
||||||
|
self::assertSame(12, $int);
|
||||||
|
|
||||||
|
$intv->set(" 12 ");
|
||||||
|
self::assertSame(12, $int);
|
||||||
|
|
||||||
|
self::assertException(Exception::class, $f(true));
|
||||||
|
self::assertException(Exception::class, $f(false));
|
||||||
|
self::assertException(Exception::class, $f("a"));
|
||||||
|
self::assertException(Exception::class, $f([]));
|
||||||
|
self::assertException(Exception::class, $f(["a"]));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testUnionTypes() {
|
||||||
|
# l'ordre des types est respecté
|
||||||
|
Schema::ns($schema, ["string|int"]);
|
||||||
|
/** @var ScalarValue $siv */
|
||||||
|
$schema->nv($siv, $si);
|
||||||
|
|
||||||
|
$siv->set("12");
|
||||||
|
self::assertSame("12", $si);
|
||||||
|
$siv->set(12);
|
||||||
|
self::assertSame(12, $si);
|
||||||
|
|
||||||
|
Schema::ns($schema, ["int|string"]);
|
||||||
|
/** @var ScalarValue $siv */
|
||||||
|
$schema->nv($siv, $si);
|
||||||
|
|
||||||
|
$siv->set("12");
|
||||||
|
self::assertSame(12, $si);
|
||||||
|
$siv->set(12);
|
||||||
|
self::assertSame(12, $si);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\schema;
|
namespace nur\sery\schema\schemas;
|
||||||
|
|
||||||
use nulib\tests\TestCase;
|
use nulib\tests\TestCase;
|
||||||
|
use nur\sery\schema\SchemaException;
|
||||||
|
use nur\sery\schema\schemas\ScalarSchema;
|
||||||
|
|
||||||
class ScalarSchemaTest extends TestCase {
|
class ScalarSchemaTest extends TestCase {
|
||||||
const NULL_SCHEMA = [
|
const NULL_SCHEMA = [
|
||||||
|
@ -20,7 +22,7 @@ class ScalarSchemaTest extends TestCase {
|
||||||
"format" => null,
|
"format" => null,
|
||||||
"" => ["scalar"],
|
"" => ["scalar"],
|
||||||
"name" => null,
|
"name" => null,
|
||||||
"key" => null,
|
"pkey" => null,
|
||||||
"header" => null,
|
"header" => null,
|
||||||
"composite" => null,
|
"composite" => null,
|
||||||
];
|
];
|
Loading…
Reference in New Issue