validator icon indicating copy to clipboard operation
validator copied to clipboard

Add `CallbackRule` rule

Open vjik opened this issue 2 months ago • 9 comments

This is analogue of Callback but it returns a different rule that is already being applied.

Example of usage:

/**
 * @var array<int, string>
 */
private readonly array $categories;

#[CallbackRule(method: categoryIdRule)]
public int|null $categoryId = null;

private function categoryIdRule(): RuleInterface
{
    return new In(array_keys($this->categories));
}

vjik avatar Sep 10 '25 12:09 vjik

How this example may be implemented with Callback rule?

BoShurik avatar Sep 10 '25 12:09 BoShurik

How this example may be implemented with Callback rule?

Only with manual validation in categoryIdRule method

vjik avatar Sep 10 '25 12:09 vjik

Is it bad?

BoShurik avatar Sep 10 '25 12:09 BoShurik

Is it bad?

It's not convenient

vjik avatar Sep 10 '25 12:09 vjik

Something like this?

/**
 * @var array<int, string>
 */
private readonly array $categories;

#[Callback(method: categoryIdRule)]
public int|null $categoryId = null;

private function categoryIdRule(mixed $value, RuleInterface $rule, ValidationContext $context): Result
{
    return $context->validate($value, new In(array_keys($this->categories)));
}

BoShurik avatar Sep 10 '25 13:09 BoShurik

Something like this?

/**

  • @var array<int, string> */ private readonly array $categories;

#[Callback(method: categoryIdRule)] public int|null $categoryId = null;

private function categoryIdRule(mixed $value, RuleInterface $rule, ValidationContext $context): Result { return $context->validate($value, new In(array_keys($this->categories))); }

Yes

vjik avatar Sep 10 '25 13:09 vjik

I'm not sure this worth it. It only removes $context->validate($value part

BoShurik avatar Sep 10 '25 13:09 BoShurik

While this new syntax removes some code, it is quite confusing since it adds a third way to do the same thing. One way is what @BoShurik suggested (a bit longer but is clear about what happens there), another is by implementing RulesProviderInterface (also clear, the only disadvantage is that declaration isn't at the same place as the property).

Personally, I'd avoid adding another way to do the same thing.

samdark avatar Sep 10 '25 22:09 samdark

Callable for Callback:

private function categoryIdRule(mixed $value, RuleInterface $rule, ValidationContext $context): Result
{
    return $context->validate($value, new In(array_keys($this->categories)));
}

Callable for CallbackRule:

private function categoryIdRule(): RuleInterface
{
    return new In(array_keys($this->categories));
}

Seems, CallbackRule usage is more clearly. Also not need remember this: mixed $value, RuleInterface $rule, ValidationContext $context (no autocomplete for callable parameters).

vjik avatar Sep 12 '25 09:09 vjik