<?php
namespace nur\b\values;

use Throwable;

/**
 * Interface IValue: wrapper vers une valeur avec éventuellement l'une de
 * propriétés suivante:
 * - indéfinie
 * - indisponible (en erreur)
 * - définie mais nulle
 * - définie non nulle
 * Une valeur peut être mutable ou non.
 */
interface IProxyValue extends IValueState {
  /** tester si is_undef() peut retourner true */
  function allowUndef(): bool;
  /** tester si is_null() peut retourner true */
  function allowNull(): bool;
  /** tester si is_error() peut retourner true */
  function allowError(): bool;

  /** tester si la valeur est indéfinie */
  function isUndef(): bool;
  /** tester si la valeur est définie et nulle */
  function isNull(): bool;
  /** tester si la valeur n'est pas disponible à cause d'une erreur */
  function isError(): bool;
  /** tester si la valeur est définie et non nulle */
  function isValue(): bool;
  /** tester si la valeur est modifiable */
  function isMutable(): bool;

  /**
   * En fonction de l'état actuel:
   * - retourner la valeur si elle est définie
   * - retourner $default si la valeur est indéfinie
   * - lancer l'exception si is_error() est vrai
   */
  function get($default=null);

  /**
   * obtenir l'exception si is_error() est vrai
   *
   * @throw ProxyValueException si ce n'est pas une erreur
   */
  function getError(): Throwable;

  /**
   * modifier la valeur. retourner la valeur précédente
   *
   * @throws ProxyValueException si cet objet n'est pas modifiable
   */
  function set($value);

  /**
   * rétablir cet objet à l'état indéfini
   *
   * @throws ProxyValueException si cet objet n'est pas modifiable ou ne
   * supporte pas l'état "indéfini"
   */
  function reset();
}