Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: valid rule set, type templates, nested rule set #2

Closed
wants to merge 8 commits into from

Commits on Nov 13, 2023

  1. feat: adds RuleSet::createValidResultSet()

    This method makes it possible to create an initial valid result set for use in populating a form.
    Having this method makes the following possible:
    
    ```php
    <?php $form = $ruleSet->createValidResultSet(); ?>
    
    <!-- In a template: -->
    <input type="text" name="first" value="<?= $this->e($form->first->value) ?>" />
    <?php if (! $form->first->isValid): ?>
    <p class="text-danger">The value you provided is invalid: <?= $this->e($form->first->message) ?></p>
    <?php endif ?>
    ```
    
    To make the tests work, I also needed to provide an `__isset()` implementation for `ResultSet`.
    weierophinney committed Nov 13, 2023
    Configuration menu
    Copy the full SHA
    5a83385 View commit details
    Browse the repository at this point in the history
  2. feat: complete functionality of RuleSet::createValidResultSet()

    Rounds out remaining functionality of `createValidResultSet()`:
    
    - ResultSet MUST NOT contain mappings for any `$valueMap` keys NOT in the rule set
    - ResultSet MUST use `null` for any OPTIONAL rules with no default value set
    - ResultSet MUST raise an exception if a key does not exist in the `$valueMap`, maps to a required rule, but has no default value.
      - Adds `RequiredRuleWithNoDefaultValueException` as the exception type for this
    - Method MUST create a `ResultSet` of the type provided in `$resultSetClass` if a class was provided.
      - This required making the `ResultSet` class non-final; all methods were marked final, however.
    
    To make this functionality more predictable and useful to developers:
    
    - Updated `Result` to add a `@template T` annotation, and assigns `@var T` to the `$value` property.
    - This allows the following patterns:
      - Extending `ResultSet` and defining `@property(-read)` mappings:
    
        ```php
        /**
         * @property-read Result<int> $count
         * @property-read Result<string> $title
         */
        class CustomResultSet extends ResultSet { }
        ```
    
      - Providing a template for a returned result set:
    
        ```php
        /** @var ResultSet{count: Result<int>, title: Result<string>} $form */
        ```
    weierophinney committed Nov 13, 2023
    Configuration menu
    Copy the full SHA
    1e9162b View commit details
    Browse the repository at this point in the history

Commits on Nov 14, 2023

  1. feat: proper Psalm templates, optional result set class

    - Moves the definition of a custom result set class to use with a rule set to a new named constructor, `RuleSet::createWithResultSetClass()`.
      - This means that for the 80% use case, you will just use the constructor, with or without rules.
      - When you want to specify a custom result set class to use, use the named constructor.
    
    - You can provide Psalm/PHPStan hints when creating a ResultSet or RuleSet
    
      ```php
      /** @var RuleSet<ResultSet> $ruleSet */
      $ruleSet = new RuleSet();
    
      /** @var ResultSet{title: string, description: string, createdDate: DateTimeImmutable} $result */
      $result = $ruleSet->validate($data);
      ```
    weierophinney committed Nov 14, 2023
    Configuration menu
    Copy the full SHA
    fcbc13c View commit details
    Browse the repository at this point in the history
  2. docs: document Psalm annotations for typing

    - Makes `RuleSet::$resultSetClass` protected, to simplify extension.
    - Documents how to provide types for results, result sets, and rule sets via template annotations.
    weierophinney committed Nov 14, 2023
    Configuration menu
    Copy the full SHA
    f47c426 View commit details
    Browse the repository at this point in the history
  3. docs: document the RuleSet::createValidResultSet() method

    Documents it and provides some examples.
    weierophinney committed Nov 14, 2023
    Configuration menu
    Copy the full SHA
    145756c View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    262125c View commit details
    Browse the repository at this point in the history
  5. feat: allow nested results

    - Removes `final` and `readonly` keywords from `Result`.
      - All properties are marked readonly
      - All methods are marked final
      - Named constructors use `static` when creating new instances, and `@return Result<T>`
      - constructor is made protected and marked final, to allow Psalm to validate that the named constructors will work with the class constructor
    - `NestedResult` extends `Result, and adds `__isset()` and `__get()` implementations that check for nested result sets and the properties it defines.
    weierophinney committed Nov 14, 2023
    Configuration menu
    Copy the full SHA
    aee781e View commit details
    Browse the repository at this point in the history
  6. Configuration menu
    Copy the full SHA
    107a841 View commit details
    Browse the repository at this point in the history