Lines 100.00% 16 / 16
Methods 100.00% 6 / 6
Classes 100.00% 1 / 1
Name Lines Methods CRAP
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 of 100.00% 1 / 1 100.00% 1 / 1 1
 validate 100.00% 5 / 5 100.00% 1 / 1 3
 [Lucent\Validation\Concerns\TracksFailure] defaultMessage 100.00% 1 / 1 100.00% 1 / 1 1
 [Lucent\Validation\Constraint] withMessage 100.00% 2 / 2 100.00% 1 / 1 1
 [Lucent\Validation\Constraint] message 100.00% 6 / 6 100.00% 1 / 1 3
 [Lucent\Validation\Constraint] defaultMessage n/a 0 / 0 n/a 0 / 0 0
16final class All extends Constraint
17{
18    use TracksFailure;
19
20    /**
21     * @param array<int, Constraint> $constraints The constraints to apply.
22     */
23    private function __construct(private readonly array $constraints) {}
24
25    /**
26     * Create an "all" combinator from one or more constraints.
27     *
28     * @param Constraint ...$constraints The constraints that must all pass.
29     * @return self A new All instance.
30     */
31    public static function of(Constraint ...$constraints): self
32    {
33        return new self($constraints);
34    }
35
36    /**
37     * Validate that every wrapped constraint passes.
38     *
39     * Stops at the first failing constraint and records it as the failure
40     * used to build the error message.
41     *
42     * @param FieldContext $ctx The context of the field being validated.
43     * @return bool True if all constraints pass, false otherwise.
44     */
45    #[\Override]
46    public function validate(FieldContext $ctx): bool
47    {
48        foreach ($this->constraints as $constraint) {
49            if (!$constraint->validate($ctx)) {
50                $ctx->failedConstraint = $constraint;
51                return false;
52            }
53        }
54
55        return true;
56    }
57}

From Lucent\Validation\Concerns\TracksFailure

9trait TracksFailure
10{
11    /**
12     * Delegate the error message to the constraint that failed.
13     *
14     * The failing constraint is read from the field context, where it was
15     * recorded by {@see \Lucent\Validation\Combinators\All::validate()}.
16     * Returns null when no constraint failed (e.g. the composite passed, or
17     * the failing constraint itself reports no message), so the parent skips
18     * adding a redundant generic error.
19     *
20     * @return string|\Closure(FieldContext): ?string|null The failing constraint's message or closure.
21     */
22    #[\Override]
23    protected function defaultMessage(): string|\Closure|null
24    {
25        return fn(FieldContext $ctx) => $ctx->failedConstraint?->message($ctx);
26    }
27}

Inherited from Lucent\Validation\Constraint

38    final public function withMessage(string|\Closure $message): static
39    {
40        $this->customMessage = $message;
41        return $this;
42    }
56    final public function message(FieldContext $ctx): ?string
57    {
58        $message = $this->customMessage ?? $this->defaultMessage();
59
60        if ($message === null) {
61            return null;
62        }
63
64        if ($message instanceof \Closure) {
65            return call_user_func($message, $ctx);
66        }
67
68        return $message;
69    }
81    abstract protected function defaultMessage(): string|\Closure|null;