# nulib\schema

* le type d'une valeur est celui qu'elle doit avoir *si* elle est spécifiée
  * required indique s'il est requis de spécifier la valeur
  * un type non nullable avec une valeur par défaut null signifie qu'il n'y a pas de valeur par défaut

* deux modes d'opération pour les schéma
  * check -- vérifier simplement si les valeurs sont dans le bon type
    * ça ne fonctionne que pour les types scalaires standard
    * autoconv pour les cas simples, e.g pour le type int "42" devient 42
  * verifix -- convertir les valeurs au bon type
l'idée générale est de gagner du temps si on veut juste vérifier par exemple
les valeurs provenant d'une base de données, mais il faut voir si ça change
vraiment quelque chose

* rajouter l'attribut "size" pour spécifier la taille maximale des valeurs
  * cela pourrait servir pour générer automatiquement des tables SQL
  * ou pour modéliser un schéma FSV
* support `max_size`, qui diffère de `size` en ce qu'on ne spécifie qu'une
  taille maximum. sinon, faire `size` à la place de `max_size` et `fixed_size`
  à la plage de `size`

* support `allowed_values`

* valeurs composite/computed
  * analyse / vérification de la valeur complète après calcul du résultat, si
    tous les résultats sont bons
  * calcul des valeurs composites/computed par une fonction avant/après l'analyse
    globale si résultat ok
  * fonction `getter_func`, `setter_func`, `deleter_func` pour les propriétés de type
    computed
* tdate et tdatetime. qu'en est-il des autres classes (delay, etc.)
  * `parse_format` pour spécifier le format d'analyse au lieu de l'auto-détecter

* `ScalarSchema::from_property()`

* pour le support des propriétés des objets, il faudrait pouvoir spécifier
  comment instancier l'objet. je ne sais pas si ça doit se mettre au niveau du
  type, du schéma, ou autre
  ~~~php
  Schema::ns($schema, [
    "rt" => ["?string", "required" => true],
    "rtd" => ["?int", "required" => true, "default" => 42],
    "ot" => ["?int"],
    "otd" => ["?string", "default" => "hello"],
    "ot2" => ["int"],
    "" => ["assoc",
      "class" => MyClass::class,
    ],
  ]);

  # peut provisionner la classe suivante
  class MyClass {
    public ?string $rt;
    public ?int $rtd = 42;
    public ?int $ot = null;
    public ?string $otd = "hello";
    public int $ot2 = 0;
  }
  ~~~
  il y a potentiellement un problème d'oeuf et de poule si on se sert de ce
  genre de définitions pour autogénérer la classe

* l'argument $format de AssocWrapper::format() est un tableau associatif
  `[$key => $format]`
  cela permet de spécifier des format spécifiques pour certains champs.
  * cela signifie que la valeur de retour n'est pas string :-(
    retourner string|array

* dans AssocSchema, support `[key_prefix]` qui permet de spécifier un préfixe
  commun aux champs dans le tableau destination, e.g
  ~~~php
  $wrapper = Schema::ns($schema, [
    "a" => "?string",
    "b" => "?int",
  ])->newWrapper();
  $value = ["x_a" => 5, "x_b" => "10"],
  $wrapper->reset($value, null, [
    "key_prefix" => "x_",
  ]);
  # $value vaut ["x_a" => "5", "x_b" => 10];
  ~~~
  définir si le préfixe doit être spécifié sur le schéma ou sur la valeur...
  actuellement, le code ne permet pas de définir de tels paramètres...

  alternative: c'est lors de la *définition* du schéma que le préfixe est ajouté
  e.g
  ~~~php
  $wrapper = Schema::ns($schema, [
    "a" => "?string",
    "b" => "?int",
  ], [
    "key_prefix" => "x_",
  ])->newWrapper();
  $value = ["x_a" => 5, "x_b" => "10"],
  $wrapper->reset($value);
  # $value vaut ["x_a" => "5", "x_b" => 10];
  ~~~
* 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
  const SCHEMA = ["first" => DEF, "second" => DEF];
  const ARRAY = ["first", "second"];
  ~~~
  la valeur normalisée de `ARRAY` est `["first" => "first", "second" => "second"]`

  cependant, dans certaines circonstances (notamment pour des paramètres), on
  devrait pouvoir considérer une valeur indexée comme un flag, i.e la valeur
  normalisée de ARRAY serait `["first" => true, "second" => true]`

  la définition de ces "circonstances" est encore à faire: soit un paramètre
  lors de la définition du schéma, soit un truc magique du genre "toutes les
  valeurs séquentielles sont des clés du schéma", soit un mode automatique
  activé par un paramètre où une valeur `"val"` devient `"val"=>true` si la clé
  "val" existe dans le schéma
* pour les schémas associatifs, support de la définition de valeurs de suite avec
  la clé "..." e.g
  ~~~php
  const SCHEMA = [
    "a" => "string",
    "b" => "bool",
    "..." => "int",
  ];
  # pourrait modéliser ["first", true, 1, 2, 3]
  ~~~
  et on aurait alors `[[type]]` qui est équivalent à `["..." => type]`
  et donc ListSchema est un cas particulier de AssocSchema (qui pourrait être
  renommé ArraySchema)

-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary