tstring et trawstring
This commit is contained in:
parent
1685a40906
commit
1aa266b509
@ -3,6 +3,6 @@ namespace nur\sery\wip\schema\_assoc;
|
||||
|
||||
use nur\sery\wip\schema\Result;
|
||||
|
||||
class AssocResult extends Result {
|
||||
abstract/*XXX*/ class AssocResult extends Result {
|
||||
function isAssoc(?AssocResult &$assoc=null): bool { $assoc = $this; return true;}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
namespace nur\sery\wip\schema\_assoc;
|
||||
|
||||
use nur\sery\cl;
|
||||
use nur\sery\ref\schema\ref_schema;
|
||||
use nulib\cl;
|
||||
use nulib\ref\schema\ref_schema;
|
||||
use nur\sery\wip\schema\Schema;
|
||||
use nur\sery\wip\schema\Value;
|
||||
|
||||
|
@ -4,7 +4,7 @@ namespace nur\sery\wip\schema\_assoc;
|
||||
use nur\sery\wip\schema\Result;
|
||||
use nur\sery\wip\schema\Value;
|
||||
|
||||
class AssocValue extends Value {
|
||||
abstract/*XXX*/ class AssocValue extends Value {
|
||||
function isAssoc(?AssocValue &$assoc=null): bool { $assoc = $this; return true; }
|
||||
|
||||
function ensureKeys(): bool {
|
||||
|
@ -3,6 +3,6 @@ namespace nur\sery\wip\schema\_list;
|
||||
|
||||
use nur\sery\wip\schema\Result;
|
||||
|
||||
class ListResult extends Result {
|
||||
abstract/*XXX*/ class ListResult extends Result {
|
||||
function isList(?ListResult &$list=null): bool { $list = $this; return true;}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace nur\sery\wip\schema\_list;
|
||||
|
||||
use nur\sery\ref\schema\ref_schema;
|
||||
use nulib\ref\schema\ref_schema;
|
||||
use nur\sery\wip\schema\Schema;
|
||||
use nur\sery\wip\schema\Value;
|
||||
|
||||
|
@ -4,7 +4,7 @@ namespace nur\sery\wip\schema\_list;
|
||||
use nur\sery\wip\schema\Result;
|
||||
use nur\sery\wip\schema\Value;
|
||||
|
||||
class ListValue extends Value {
|
||||
abstract/*XXX*/ class ListValue extends Value {
|
||||
function isList(?ListValue &$list=null): bool { $list = $this; return true; }
|
||||
|
||||
function ensureKeys(): bool {
|
||||
|
@ -11,7 +11,7 @@ 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\tpkey;
|
||||
use nur\sery\wip\schema\types\tstring;
|
||||
use nur\sery\wip\schema\types\trawstring;
|
||||
use nur\sery\wip\schema\Value;
|
||||
|
||||
/**
|
||||
@ -31,6 +31,7 @@ use nur\sery\wip\schema\Value;
|
||||
* @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
|
||||
@ -142,9 +143,9 @@ class ScalarSchema extends Schema {
|
||||
$pkey = $definition["pkey"];
|
||||
$header = $definition["header"];
|
||||
if ($name === null) $name = $definitionKey;
|
||||
tstring::ensure_nstring($name);
|
||||
trawstring::ensure_nstring($name);
|
||||
tpkey::ensure_npkey($pkey);
|
||||
tstring::ensure_nstring($header);
|
||||
trawstring::ensure_nstring($header);
|
||||
if ($pkey === null) $pkey = $name;
|
||||
if ($header === null) $header = $name;
|
||||
$definition["name"] = $name;
|
||||
@ -152,7 +153,7 @@ class ScalarSchema extends Schema {
|
||||
$definition["header"] = $header;
|
||||
# autres éléments
|
||||
tarray::ensure_narray($definition["schema"]);
|
||||
tstring::ensure_nstring($definition["title"]);
|
||||
trawstring::ensure_nstring($definition["title"]);
|
||||
tbool::ensure_bool($definition["required"]);
|
||||
tbool::ensure_bool($definition["nullable"]);
|
||||
tcontent::ensure_ncontent($definition["desc"]);
|
||||
|
@ -53,7 +53,7 @@ class ScalarValue extends Value {
|
||||
$this->destKey = $destKey;
|
||||
$this->type = null;
|
||||
$this->_analyze();
|
||||
if ($verifix == null) $verifix = $this->defaultVerifix;
|
||||
if ($verifix === null) $verifix = $this->defaultVerifix;
|
||||
if ($verifix) $this->verifix();
|
||||
return $this;
|
||||
}
|
||||
@ -75,6 +75,7 @@ class ScalarValue extends Value {
|
||||
$result = $this->result;
|
||||
$result->reset();
|
||||
if (!$input->isPresent($destKey)) return $result->setMissing($schema);
|
||||
|
||||
$haveType = false;
|
||||
$types = [];
|
||||
$type = $firstType = null;
|
||||
@ -107,15 +108,18 @@ class ScalarValue extends Value {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# sinon prendre le premier type
|
||||
if (!$haveType) $type = $this->type = $firstType;
|
||||
if (!$type->isAvailable($input, $destKey)) return $result->setUnavailable($schema);
|
||||
|
||||
$value = $input->get($destKey);
|
||||
if ($type->isNull($value)) return $result->setNull($schema);
|
||||
if ($type->isValid($value, $normalized)) {
|
||||
if ($normalized) return $result->setNormalized();
|
||||
else return $result->setValid();
|
||||
}
|
||||
|
||||
if (is_string($value)) return ref_analyze::STRING;
|
||||
else return $result->setInvalid($value, $schema);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use nur\sery\wip\schema\types\tbool;
|
||||
use nur\sery\wip\schema\types\tcallable;
|
||||
use nur\sery\wip\schema\types\tfloat;
|
||||
use nur\sery\wip\schema\types\tint;
|
||||
use nur\sery\wip\schema\types\tstring;
|
||||
use nur\sery\wip\schema\types\trawstring;
|
||||
|
||||
/**
|
||||
* Class types: classe outil pour gérer le registre de types
|
||||
@ -28,6 +28,7 @@ class types {
|
||||
return self::registry()->get($name);
|
||||
}
|
||||
|
||||
static function rawstring(): trawstring { return self::get("rawstring"); }
|
||||
static function string(): tstring { return self::get("string"); }
|
||||
static function bool(): tbool { return self::get("bool"); }
|
||||
static function int(): tint { return self::get("int"); }
|
||||
|
@ -2,9 +2,11 @@
|
||||
namespace nur\sery\wip\schema\types;
|
||||
|
||||
use nulib\cl;
|
||||
use nulib\php\func;
|
||||
|
||||
class Registry {
|
||||
const TYPES = [
|
||||
"rawstring" => trawstring::class,
|
||||
"string" => tstring::class,
|
||||
"bool" => tbool::class, "boolean" => tbool::class,
|
||||
"int" => tint::class, "integer" => tint::class,
|
||||
@ -25,7 +27,11 @@ class Registry {
|
||||
/** @var IType[] */
|
||||
protected $types;
|
||||
|
||||
function get(string $name): IType {
|
||||
function get(string $name, ?array $params=null): IType {
|
||||
if ($params !== null) {
|
||||
$class = self::TYPES[$name];
|
||||
return func::with([$class, false, $params])->invoke();
|
||||
}
|
||||
$type = cl::get($this->types, $name);
|
||||
if ($type === null) {
|
||||
$class = self::TYPES[$name];
|
||||
|
@ -4,6 +4,12 @@ namespace nur\sery\wip\schema\types;
|
||||
use nur\sery\wip\schema\input\Input;
|
||||
|
||||
abstract class _tsimple implements IType {
|
||||
function __construct(?array $params=null) {
|
||||
$this->params = $params;
|
||||
}
|
||||
|
||||
protected ?array $params;
|
||||
|
||||
function isAvailable(Input $input, $destKey): bool {
|
||||
return $input->isAvailable($destKey) && $input->get($destKey) !== false;
|
||||
}
|
||||
|
79
src/schema/types/trawstring.php
Normal file
79
src/schema/types/trawstring.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?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\Result;
|
||||
use nur\sery\wip\schema\Schema;
|
||||
|
||||
class trawstring extends _tsimple {
|
||||
const TRIM = false;
|
||||
|
||||
static function ensure_string(&$string): void {
|
||||
if (!is_string($string)) $string = strval($string);
|
||||
if (static::TRIM) $string = trim($string);
|
||||
}
|
||||
|
||||
static function ensure_nstring(&$string): void {
|
||||
if ($string !== null) self::ensure_string($string);
|
||||
}
|
||||
|
||||
function __construct(?array $params=null) {
|
||||
parent::__construct($params);
|
||||
$this->trim = boolval($this->params["trim"] ?? static::TRIM);
|
||||
}
|
||||
|
||||
protected bool $trim;
|
||||
|
||||
function isNull($value): bool {
|
||||
return $value === null;
|
||||
}
|
||||
|
||||
protected function check_normalized(string $value, bool $trim): bool {
|
||||
if ($trim && $value !== "") {
|
||||
if (preg_match('/^\s+/', $value)) {
|
||||
return false;
|
||||
} elseif (preg_match('/\s+$/', $value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function isValid($value, ?bool &$normalized=null): bool {
|
||||
if (is_string($value)) {
|
||||
$normalized = self::check_normalized($value, $this->trim);
|
||||
return true;
|
||||
}
|
||||
return is_scalar($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var ScalarResult $result
|
||||
* @var ScalarSchema $schema
|
||||
*/
|
||||
function verifix(&$value, Result &$result, Schema $schema): bool {
|
||||
if (is_string($value)) {
|
||||
$normalized = false;
|
||||
if ($this->trim) {
|
||||
$orig = $value;
|
||||
$value = trim($value);
|
||||
$normalized = $value !== $orig;
|
||||
}
|
||||
$result->setNormalized();
|
||||
return $normalized;
|
||||
} elseif (is_scalar($value)) {
|
||||
$value = strval($value);
|
||||
if ($this->trim) $value = trim($value);
|
||||
$result->setNormalized();
|
||||
return true;
|
||||
} else {
|
||||
$result->setInvalid($value, $schema);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function format($value, $format=null): string {
|
||||
return strval($value);
|
||||
}
|
||||
}
|
@ -1,48 +1,6 @@
|
||||
<?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\Result;
|
||||
use nur\sery\wip\schema\Schema;
|
||||
|
||||
class tstring extends _tsimple {
|
||||
static function ensure_string(&$string): void {
|
||||
if (!is_string($string)) $string = strval($string);
|
||||
}
|
||||
|
||||
static function ensure_nstring(&$string): void {
|
||||
if ($string !== null) self::ensure_string($string);
|
||||
}
|
||||
|
||||
function isNull($value): bool {
|
||||
return $value === null;
|
||||
}
|
||||
|
||||
function isValid($value, ?bool &$normalized=null): bool {
|
||||
$normalized = is_string($value);
|
||||
return is_scalar($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var ScalarResult $result
|
||||
* @var ScalarSchema $schema
|
||||
*/
|
||||
function verifix(&$value, Result &$result, Schema $schema): bool {
|
||||
if (is_string($value)) {
|
||||
$result->setNormalized();
|
||||
return false;
|
||||
} elseif (is_scalar($value)) {
|
||||
$value = strval($value);
|
||||
$result->setValid();
|
||||
return true;
|
||||
} else {
|
||||
$result->setInvalid($value, $schema);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function format($value, $format=null): string {
|
||||
return strval($value);
|
||||
}
|
||||
class tstring extends trawstring {
|
||||
const TRIM = true;
|
||||
}
|
||||
|
162
tests/wip/schema/_scalar/ScalarValueTest.php
Normal file
162
tests/wip/schema/_scalar/ScalarValueTest.php
Normal file
@ -0,0 +1,162 @@
|
||||
<?php
|
||||
namespace nur\sery\wip\schema\_scalar;
|
||||
|
||||
use nulib\tests\TestCase;
|
||||
use nulib\ValueException;
|
||||
|
||||
class ScalarValueTest extends TestCase {
|
||||
function checkValue(ScalarValue $value, $dest, bool $present, bool $available, bool $valid, bool $normalized): void {
|
||||
self::assertSame($dest, $value->get(), "value");
|
||||
self::assertSame($present, $value->isPresent(), "present");
|
||||
self::assertSame($available, $value->isAvailable(), "available");
|
||||
self::assertSame($valid, $value->isValid(), "valid");
|
||||
self::assertSame($normalized, $value->isNormalized(), "normalized");
|
||||
}
|
||||
|
||||
function testRawstring() {
|
||||
$schema = new ScalarSchema("rawstring");
|
||||
$value = $schema->newValue();
|
||||
|
||||
$string = null;
|
||||
$value->reset($string, null, false);
|
||||
$this->checkValue($value, null, true, true, false, false);
|
||||
self::assertException(ValueException::class, function() use (&$value) {
|
||||
$string = null;
|
||||
$value->reset($string);
|
||||
});
|
||||
|
||||
$string = ""; $value->reset($string, null, false);
|
||||
$this->checkValue($value, "", true, true, true, true);
|
||||
$string = ""; $value->reset($string);
|
||||
$this->checkValue($value, "", true, true, true, true);
|
||||
|
||||
$string = " "; $value->reset($string, null, false);
|
||||
$this->checkValue($value, " ", true, true, true, true);
|
||||
$string = " "; $value->reset($string);
|
||||
$this->checkValue($value, " ", true, true, true, true);
|
||||
|
||||
$string = "value"; $value->reset($string, null, false);
|
||||
$this->checkValue($value, "value", true, true, true, true);
|
||||
$string = "value"; $value->reset($string);
|
||||
$this->checkValue($value, "value", true, true, true, true);
|
||||
|
||||
$string = " value "; $value->reset($string, null, false);
|
||||
$this->checkValue($value, " value ", true, true, true, true);
|
||||
$string = " value "; $value->reset($string);
|
||||
$this->checkValue($value, " value ", true, true, true, true);
|
||||
|
||||
$string = true; $value->reset($string, null, false);
|
||||
$this->checkValue($value, true, true, true, true, false);
|
||||
$string = true; $value->reset($string);
|
||||
$this->checkValue($value, "1", true, true, true, true);
|
||||
|
||||
$string = false; $value->reset($string, null, false);
|
||||
$this->checkValue($value, null, true, false, true, true);
|
||||
$string = false; $value->reset($string);
|
||||
$this->checkValue($value, null, true, false, true, true);
|
||||
|
||||
$string = 42; $value->reset($string, null, false);
|
||||
$this->checkValue($value, 42, true, true, true, false);
|
||||
$string = 42; $value->reset($string);
|
||||
$this->checkValue($value, "42", true, true, true, true);
|
||||
|
||||
$string = []; $value->reset($string, null, false);
|
||||
$this->checkValue($value, [], true, true, false, false);
|
||||
self::assertException(ValueException::class, function() use (&$value) {
|
||||
$string = null;
|
||||
$value->reset($string);
|
||||
});
|
||||
|
||||
## Tester nullable
|
||||
$schema = new ScalarSchema("?rawstring");
|
||||
$value = $schema->newValue();
|
||||
|
||||
$string = null; $value->reset($string, null, false);
|
||||
$this->checkValue($value, null, true, true, true, true);
|
||||
$string = null; $value->reset($string, null);
|
||||
$this->checkValue($value, null, true, true, true, true);
|
||||
|
||||
## Tester required
|
||||
$schema = new ScalarSchema(["rawstring", "required" => true]);
|
||||
$value = $schema->newValue();
|
||||
|
||||
$string = false; $value->reset($string, null, false);
|
||||
$this->checkValue($value, null, true, false, false, false);
|
||||
self::assertException(ValueException::class, function() use (&$value) {
|
||||
$string = false; $value->reset($string);
|
||||
});
|
||||
}
|
||||
|
||||
function testString() {
|
||||
$schema = new ScalarSchema("string");
|
||||
$value = $schema->newValue();
|
||||
|
||||
$string = null; $value->reset($string, null, false);
|
||||
$this->checkValue($value, null, true, true, false, false);
|
||||
self::assertException(ValueException::class, function() use (&$value) {
|
||||
$string = null;
|
||||
$value->reset($string);
|
||||
});
|
||||
|
||||
$string = ""; $value->reset($string, null, false);
|
||||
$this->checkValue($value, "", true, true, true, true);
|
||||
$string = ""; $value->reset($string);
|
||||
$this->checkValue($value, "", true, true, true, true);
|
||||
|
||||
$string = " "; $value->reset($string, null, false);
|
||||
$this->checkValue($value, " ", true, true, true, false);
|
||||
$string = " "; $value->reset($string);
|
||||
$this->checkValue($value, "", true, true, true, true);
|
||||
|
||||
$string = "value"; $value->reset($string, null, false);
|
||||
$this->checkValue($value, "value", true, true, true, true);
|
||||
$string = "value"; $value->reset($string);
|
||||
$this->checkValue($value, "value", true, true, true, true);
|
||||
|
||||
$string = " value "; $value->reset($string, null, false);
|
||||
$this->checkValue($value, " value ", true, true, true, false);
|
||||
$string = " value "; $value->reset($string);
|
||||
$this->checkValue($value, "value", true, true, true, true);
|
||||
|
||||
$string = true; $value->reset($string, null, false);
|
||||
$this->checkValue($value, true, true, true, true, false);
|
||||
$string = true; $value->reset($string);
|
||||
$this->checkValue($value, "1", true, true, true, true);
|
||||
|
||||
$string = false; $value->reset($string, null, false);
|
||||
$this->checkValue($value, null, true, false, true, true);
|
||||
$string = false; $value->reset($string);
|
||||
$this->checkValue($value, null, true, false, true, true);
|
||||
|
||||
$string = 42; $value->reset($string, null, false);
|
||||
$this->checkValue($value, 42, true, true, true, false);
|
||||
$string = 42; $value->reset($string);
|
||||
$this->checkValue($value, "42", true, true, true, true);
|
||||
|
||||
$string = []; $value->reset($string, null, false);
|
||||
$this->checkValue($value, [], true, true, false, false);
|
||||
self::assertException(ValueException::class, function() use (&$value) {
|
||||
$string = null;
|
||||
$value->reset($string);
|
||||
});
|
||||
|
||||
## Tester nullable
|
||||
$schema = new ScalarSchema("?string");
|
||||
$value = $schema->newValue();
|
||||
|
||||
$string = null; $value->reset($string, null, false);
|
||||
$this->checkValue($value, null, true, true, true, true);
|
||||
$string = null; $value->reset($string, null);
|
||||
$this->checkValue($value, null, true, true, true, true);
|
||||
|
||||
## Tester required
|
||||
$schema = new ScalarSchema(["string", "required" => true]);
|
||||
$value = $schema->newValue();
|
||||
|
||||
$string = false; $value->reset($string, null, false);
|
||||
$this->checkValue($value, null, true, false, false, false);
|
||||
self::assertException(ValueException::class, function() use (&$value) {
|
||||
$string = false; $value->reset($string);
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user