modifs.mineures sans commentaires

This commit is contained in:
Jephté Clain 2023-11-28 00:20:42 +04:00
parent aa77c915d8
commit 2da6cef41a
15 changed files with 120 additions and 77 deletions

View File

@ -26,6 +26,15 @@ class Result {
/** @var array */ /** @var array */
protected $result; protected $result;
/**
* Obtenir la liste des clés valides pour les valeurs accessibles via cet
* objet
*/
abstract function getKeys(): array;
/** obtenir un objet pour gérer la valeur spécifiée */
abstract function getResult($key=null): Result;
function __get($name) { function __get($name) {
return $this->result[$name]; return $this->result[$name];
} }

View File

@ -4,13 +4,14 @@ namespace nur\sery\schema;
use ArrayAccess; use ArrayAccess;
use LogicException; use LogicException;
use nulib\cl; use nulib\cl;
use nur\sery\schema\schemas\AssocSchema; use nur\sery\schema\_assoc\AssocSchema;
use nur\sery\schema\schemas\ListSchema; use nur\sery\schema\_list\ListSchema;
use nur\sery\schema\schemas\ScalarSchema; use nur\sery\schema\_scalar\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 de {@link Schema} à partir d'une
* définition de schéma
*/ */
static function ns(?Schema &$schema, $definition): self { static function ns(?Schema &$schema, $definition): self {
if ($schema === null) { if ($schema === null) {
@ -27,6 +28,19 @@ abstract class Schema implements ArrayAccess {
return $schema; return $schema;
} }
/**
* Créer si besoin une nouvelle instance de {@link Value} qui référence la
* variable $dest
*/
static function nv(?Value &$value=null, &$dest=null, $key=null, ?Schema &$schema=null, $definition=null): Value {
if ($definition === null) {
# bien que techniquement, $definition peut être null (il s'agit alors du
# schéma d'un scalaire quelconque), on ne l'autorise pas ici
throw SchemaException::invalid_schema("definition is required");
}
return self::ns($schema, $definition)->newValue($value, $dest, $key);
}
/** /**
* @var array définition du schéma, à redéfinir le cas échéant dans une classe * @var array définition du schéma, à redéfinir le cas échéant dans une classe
* dérivée * dérivée
@ -43,11 +57,7 @@ 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 newValue(?Value &$value=null, &$dest=null, $key=null): Value;
* 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

View File

@ -1,27 +1,53 @@
<?php <?php
namespace nur\sery\schema; namespace nur\sery\schema;
use ArrayAccess;
use IteratorAggregate;
use nur\sery\schema\types\IType; 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 { abstract class Value implements ArrayAccess, IteratorAggregate {
function isAssoc(?AssocValue &$assoc=null): bool { return false; } /** spécifier la valeur destination gérée par cet objet */
function isList(?ListValue &$list=null): bool { return false; } abstract function reset(&$dest, $destKey=null, bool $verifix=true): self;
function isScalar(?ScalarValue &$scalar=null): bool { return false; }
abstract function reset(&$dest, $key=null, bool $verifix=true): self; /**
* Obtenir la liste des clés valides pour les valeurs accessibles via cet
* objet
*/
abstract function getKeys(): array;
/** retourner le type associé à cette valeur */ /** obtenir un objet pour gérer la valeur spécifiée */
abstract function getValue($key=null): Value;
function getIterator() {
foreach ($this->getKeys() as $key) {
yield $key => $this->getValue($key);
}
}
/** retourner le type associé à la valeur */
abstract function getType(): IType; abstract function getType(): IType;
/** retourner true si la valeur existe */ /** retourner true si la valeur existe */
abstract function exists(): bool; abstract function exists(): bool;
/** supprimer la valeur */
abstract function unset(): void;
/** remplacer la valeur */
abstract function set($value): self;
/** obtenir le résultat de l'appel de la fonction {@link set()} */
abstract function result(): Result;
/** retourner true si la valeur est valide */ /** retourner true si la valeur est valide */
abstract function valid(): bool; abstract function valid(): bool;
/** obtenir la valeur */
abstract function get($default=null);
/** retourner true si la valeur est dans sa forme normalisée */ /** retourner true si la valeur est dans sa forme normalisée */
abstract function normalized(): bool; abstract function normalized(): bool;
/** formatter la valeur pour affichage */
abstract function format($format=null): string;
} }

View File

@ -0,0 +1,7 @@
<?php
namespace nur\sery\schema\_assoc;
use nur\sery\schema\Result;
class AssocResult extends Result {
}

View File

@ -1,12 +1,10 @@
<?php <?php
namespace nur\sery\schema\schemas; namespace nur\sery\schema\_assoc;
use nulib\cl; use nulib\cl;
use nur\sery\schema\input\Input; use nur\sery\schema\input\Input;
use nur\sery\schema\Schema; use nur\sery\schema\Schema;
use nur\sery\schema\Value; 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 */
@ -47,7 +45,7 @@ class AssocSchema extends Schema {
return true; return true;
} }
function nv(?Value &$value=null, &$dest=null, $key=null): Value { function newValue(?Value &$value=null, &$dest=null, $key=null): Value {
if (!($value instanceof AssocValue)) $value = new AssocValue($this); if (!($value instanceof AssocValue)) $value = new AssocValue($this);
if ($dest instanceof Input) $input = $dest; if ($dest instanceof Input) $input = $dest;
else $input = new Input($dest); else $input = new Input($dest);

View File

@ -1,8 +1,8 @@
<?php <?php
namespace nur\sery\schema\values; namespace nur\sery\schema\_assoc;
use nur\sery\schema\Value;
use nur\sery\schema\Result; use nur\sery\schema\Result;
use nur\sery\schema\Value;
class AssocValue extends Value { class AssocValue extends Value {
function isAssoc(?AssocValue &$assoc=null): bool { $assoc = $this; return true; } function isAssoc(?AssocValue &$assoc=null): bool { $assoc = $this; return true; }

View File

@ -0,0 +1,7 @@
<?php
namespace nur\sery\schema\_list;
use nur\sery\schema\Result;
class ListResult extends Result {
}

View File

@ -1,10 +1,8 @@
<?php <?php
namespace nur\sery\schema\schemas; namespace nur\sery\schema\_list;
use nur\sery\schema\input\Input;
use nur\sery\schema\Schema; use nur\sery\schema\Schema;
use nur\sery\schema\Value; 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 */
@ -47,10 +45,8 @@ class ListSchema extends Schema {
return true; return true;
} }
function nv(?Value &$value=null, &$dest=null, $key=null): Value { function newValue(?Value &$value=null, &$dest=null, $key=null): Value {
if (!($value instanceof ListValue)) $value = new ListValue($this); if (!($value instanceof ListValue)) $value = new ListValue($this);
if ($dest instanceof Input) $input = $dest; return $value->reset($dest, $key);
else $input = new Input($dest);
return $value->reset($input, $key);
} }
} }

View File

@ -1,5 +1,5 @@
<?php <?php
namespace nur\sery\schema\values; namespace nur\sery\schema\_list;
use nur\sery\schema\Result; use nur\sery\schema\Result;
use nur\sery\schema\Value; use nur\sery\schema\Value;

View File

@ -0,0 +1,7 @@
<?php
namespace nur\sery\schema\_scalar;
use nur\sery\schema\Result;
class ScalarResult extends Result {
}

View File

@ -1,8 +1,7 @@
<?php <?php
namespace nur\sery\schema\schemas; namespace nur\sery\schema\_scalar;
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\Schema; use nur\sery\schema\Schema;
@ -14,7 +13,6 @@ 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\Value; use nur\sery\schema\Value;
use nur\sery\schema\values\ScalarValue;
/** /**
* Class ScalarSchema * Class ScalarSchema
@ -182,7 +180,7 @@ class ScalarSchema extends Schema {
return true; return true;
} }
function nv(?Value &$value=null, &$dest=null, $key=null): Value { function newValue(?Value &$value=null, &$dest=null, $key=null): Value {
if (!($value instanceof ScalarValue)) $value = new ScalarValue($this); if (!($value instanceof ScalarValue)) $value = new ScalarValue($this);
return $value->reset($dest, $key); return $value->reset($dest, $key);
} }

View File

@ -1,9 +1,8 @@
<?php <?php
namespace nur\sery\schema\values; namespace nur\sery\schema\_scalar;
use nur\sery\schema\input\Input; use nur\sery\schema\input\Input;
use nur\sery\schema\Result; 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; use nur\sery\schema\Value;
@ -22,16 +21,16 @@ class ScalarValue extends Value {
protected $input; protected $input;
/** @var string|int clé de la valeur dans le tableau destination */ /** @var string|int clé de la valeur dans le tableau destination */
protected $key; protected $destKey;
/** @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 reset(&$dest, $key=null, bool $verifix=true): Value { function reset(&$dest, $destKey=null, bool $verifix=true): Value {
if ($dest instanceof Input) $input = $dest; if ($dest instanceof Input) $input = $dest;
else $input = new Input($dest); else $input = new Input($dest);
$this->input = $input; $this->input = $input;
$this->key = $key; $this->destKey = $destKey;
$this->result = null; $this->result = null;
#XXX résoudre les types ici? #XXX résoudre les types ici?
if ($verifix) $this->verifix(); if ($verifix) $this->verifix();
@ -39,18 +38,18 @@ class ScalarValue extends Value {
} }
function exists(): bool { function exists(): bool {
return $this->input->exists($this->key); return $this->input->exists($this->destKey);
} }
function get($default=null) { function get($default=null) {
$key = $this->key; $destKey = $this->destKey;
$input = $this->input; $input = $this->input;
if ($input->exists($key)) return $input->get($key); if ($input->exists($destKey)) return $input->get($destKey);
else return $default; else return $default;
} }
function set($value): self { function set($value): self {
$this->input->set($value, $this->key); $this->input->set($value, $this->destKey);
return $this; return $this;
} }
@ -58,7 +57,7 @@ class ScalarValue extends Value {
protected $type; protected $type;
function getType(): 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->destKey);
return $this->type; return $this->type;
} }
@ -75,7 +74,7 @@ class ScalarValue extends Value {
*/ */
function verifix(bool $throw=true, ?Result &$result=null): bool { function verifix(bool $throw=true, ?Result &$result=null): bool {
$type = $this->getType(); $type = $this->getType();
$key = $this->key; $key = $this->destKey;
if ($key === null) $modified = $type->verifix($this->input, $throw, $result); if ($key === null) $modified = $type->verifix($this->input, $throw, $result);
else $modified = $type->verifix($this->input[$key], $throw, $result); else $modified = $type->verifix($this->input[$key], $throw, $result);
$this->result = $result; $this->result = $result;
@ -91,7 +90,7 @@ class ScalarValue extends Value {
function format(?string $format=null): string { function format(?string $format=null): string {
$type = $this->getType(); $type = $this->getType();
$key = $this->key; $key = $this->destKey;
if ($key === null) return $type->format($this->input, $format); if ($key === null) return $type->format($this->input, $format);
else return $type->format($this->input[$key], $format); else return $type->format($this->input[$key], $format);
} }

View File

@ -7,19 +7,7 @@ use nur\sery\schema\Result;
* Interface IType: un type de données * Interface IType: un type de données
*/ */
interface IType { interface IType {
/**
* indiquer si la valeur a été fournie par l'utilisateur (elle doit exister
* et être non vide)
*/
function available($value, $key=null): bool;
/**
* indiquer si la valeur spécifiée existe. cette méthode permet de distinguer
* les cas "fourni par l'utilisateur mais vide" et "non fourni par l'utilisateur"
*/
function exists($value, $key=null): bool;
function verifix(&$value, bool $throw, ?Result &$result); function verifix(&$value, bool $throw, ?Result &$result);
function format($value, ?string $format); function format($value, $format=null);
} }

View File

@ -3,13 +3,12 @@ namespace nur\sery\schema;
use Exception; use Exception;
use nulib\tests\TestCase; use nulib\tests\TestCase;
use nur\sery\schema\values\ScalarValue; use nur\sery\schema\_scalar\ScalarValue;
class schemaTest extends TestCase { class schemaTest extends TestCase {
function testInt() { function testInt() {
Schema::ns($schema, "int");
/** @var ScalarValue $intv */ /** @var ScalarValue $intv */
$schema->nv($intv, $int); Schema::nv($intv, $int, null, $schema, "int");
$f = function($value) use($intv) { $f = function($value) use($intv) {
return function() use($intv, $value) { return function() use($intv, $value) {
$intv->set($value); $intv->set($value);
@ -40,9 +39,8 @@ class schemaTest extends TestCase {
} }
function testNint() { function testNint() {
Schema::ns($schema, ["?int"]);
/** @var ScalarValue $intv */ /** @var ScalarValue $intv */
$schema->nv($intv, $int); Schema::nv($intv, $int, null, $schema, "?int");
$f = function($value) use($intv) { $f = function($value) use($intv) {
return function() use($intv, $value) { return function() use($intv, $value) {
$intv->set($value); $intv->set($value);
@ -84,23 +82,23 @@ class schemaTest extends TestCase {
} }
function testUnionTypes() { function testUnionTypes() {
# l'ordre des types est respecté ## l'ordre des types doit être respecté
Schema::ns($schema, ["string|int"]);
# string puis int
/** @var ScalarValue $siv */ /** @var ScalarValue $siv */
$schema->nv($siv, $si); Schema::nv($siv, $si, null, $sis, "string|int");
$siv->set("12"); $siv->set("12");
self::assertSame("12", $si); self::assertSame("12", $si);
$siv->set(12); $siv->set(12);
self::assertSame(12, $si); self::assertSame(12, $si);
Schema::ns($schema, ["int|string"]); # int puis string
/** @var ScalarValue $siv */ Schema::nv($isv, $is, null, $iss, "int|string");
$schema->nv($siv, $si);
$siv->set("12"); $isv->set("12");
self::assertSame(12, $si); self::assertSame(12, $is);
$siv->set(12); $isv->set(12);
self::assertSame(12, $si); self::assertSame(12, $is);
} }
} }

View File

@ -3,7 +3,7 @@ namespace nur\sery\schema\schemas;
use nulib\tests\TestCase; use nulib\tests\TestCase;
use nur\sery\schema\SchemaException; use nur\sery\schema\SchemaException;
use nur\sery\schema\schemas\ScalarSchema; use nur\sery\schema\_scalar\ScalarSchema;
class ScalarSchemaTest extends TestCase { class ScalarSchemaTest extends TestCase {
const NULL_SCHEMA = [ const NULL_SCHEMA = [