Skip to content

Commit e1045a8

Browse files
committed
Refactor case sensitiveness support
This is a mid-size refactor that affects several validators. Most prominently, the ones that had an `$identical` parameter to deal with case sensitiveness. This parameter was confusing, effectively making validators such as `Contains` behave very differently for arrays versus strings. In arrays, `$identical` meant "the same type", while it in strings it meant "case sensitive". That parameter was removed, and the default behavior is now to always compare **case sensitive** and strict typing. A document explaining how to combine other validators in order to achieve case _insensitive_ comparisons was added. Additionally, the `Call` validator was refactored back to be suitable to take on the task of being a fast, quick composable validator. With the introduction of `Circuit`, we can shift the responsibility of dealing with possible mismatches to the user. This kind of type handling is demonstrated in how I refactored `Tld` to account for the type mismatch without setting error handlers.
1 parent d8e31db commit e1045a8

49 files changed

Lines changed: 276 additions & 342 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/case-sensitiveness.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<!--
2+
SPDX-FileCopyrightText: (c) Respect Project Contributors
3+
SPDX-License-Identifier: MIT
4+
-->
5+
6+
# Case Insensitive Validation
7+
8+
For most simple cases, you can use `v::call` wrappers to perform
9+
case normalization before comparison.
10+
11+
For strings:
12+
13+
```php
14+
v::call(strtolower(...), v::contains('cde'))->assert('ABCDEF');
15+
// Validation passes successfully
16+
17+
v::call(strtolower(...), v::contains('xxx'))->assert('ABCDEF');
18+
// → "abcdef" must contain "xxx"
19+
```
20+
21+
For arrays:
22+
23+
```php
24+
v::call(
25+
static fn ($i) => array_map(strtolower(...), $i),
26+
v::contains('abc')
27+
)->assert(['ABC', 'DEF']);
28+
// Validation passes successfully
29+
30+
v::call(
31+
static fn ($i) => array_map(strtolower(...), $i),
32+
v::contains('xxx')
33+
)->assert(['ABC', 'DEF']);
34+
// → `["abc", "def"]` must contain "xxx"
35+
```
36+
37+
There might be a scenario where the needle is dynamic, and you might
38+
need to normalize both sides of the comparison. This can be done with
39+
a combination of `v::call` and `v::lazy`:
40+
41+
```php
42+
$needle = 'cde';
43+
$haystack = 'ABCDEF';
44+
v::call(
45+
strtolower(...),
46+
v::lazy(
47+
static fn ($i) => v::contains(strtolower($i)),
48+
v::contains($needle)
49+
)
50+
)->assert($haystack);
51+
// Validation passes successfully
52+
```

docs/validators/Call.md

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,29 @@ v::call(
5252
// Validation passes successfully
5353
```
5454

55+
Call does not handle possible errors (type mismatches). If you need to
56+
ensure that your callback is of a certain type, use `Circuit` or handle it
57+
using a closure:
58+
59+
```php
60+
v::call('strtolower', v::equals('ABC'))->assert(123);
61+
// 𝙭 strtolower(): Argument #1 ($string) must be of type string, int given
62+
63+
v::circuit(v::stringType(), v::call('strtolower', v::equals('abc')))->assert(123);
64+
// → 123 must be a string
65+
66+
v::circuit(v::stringType(), v::call('strtolower', v::equals('abc')))->assert('ABC');
67+
// Validation passes successfully
68+
```
69+
5570
## Templates
5671

5772
### `Call::TEMPLATE_STANDARD`
5873

59-
| Mode | Template |
60-
| ---------: | :--------------------------------------------------------- |
61-
| `default` | {{input}} must be a suitable argument for {{callable}} |
62-
| `inverted` | {{input}} must not be a suitable argument for {{callable}} |
74+
| Mode | Template |
75+
| ---------: | :-------------------------- |
76+
| `default` | {{input}} must be valid |
77+
| `inverted` | {{input}} must not be valid |
6378

6479
## Template placeholders
6580

@@ -77,9 +92,10 @@ v::call(
7792

7893
## Changelog
7994

80-
| Version | Description |
81-
| ------: | :---------- |
82-
| 0.3.9 | Created |
95+
| Version | Description |
96+
| ------: | :---------------------------- |
97+
| 3.0.0 | No longer sets error handlers |
98+
| 0.3.9 | Created |
8399

84100
## See Also
85101

docs/validators/Contains.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ SPDX-License-Identifier: MIT
66
# Contains
77

88
- `Contains(mixed $containsValue)`
9-
- `Contains(mixed $containsValue, bool $identical)`
109

1110
Validates if the input contains some value.
1211

@@ -17,16 +16,26 @@ v::contains('ipsum')->assert('lorem ipsum');
1716
// Validation passes successfully
1817
```
1918

19+
20+
```php
21+
$needle = 'cDe';
22+
v::call(
23+
strtolower(...),
24+
v::lazy(
25+
static fn ($i) => v::contains(strtolower($i)),
26+
v::contains('cde')
27+
)
28+
)->assert('ABCDEF');
29+
// Validation passes successfully
30+
```
31+
2032
For arrays:
2133

2234
```php
2335
v::contains('ipsum')->assert(['ipsum', 'lorem']);
2436
// Validation passes successfully
2537
```
2638

27-
A second parameter may be passed for identical comparison instead
28-
of equal comparison.
29-
3039
Message template for this validator includes `{{containsValue}}`.
3140

3241
## Templates
@@ -52,9 +61,10 @@ Message template for this validator includes `{{containsValue}}`.
5261

5362
## Changelog
5463

55-
| Version | Description |
56-
| ------: | :---------- |
57-
| 0.3.9 | Created |
64+
| Version | Description |
65+
| ------: | :---------------------------------- |
66+
| 3.0.0 | Case-insensitive comparison removed |
67+
| 0.3.9 | Created |
5868

5969
## See Also
6070

docs/validators/ContainsAny.md

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,23 @@ SPDX-License-Identifier: MIT
66
# ContainsAny
77

88
- `ContainsAny(non-empty-array<mixed> $needles)`
9-
- `ContainsAny(non-empty-array<mixed> $needles, bool $identical)`
109

1110
Validates if the input contains at least one of defined values
1211

13-
For strings (comparing is case insensitive):
12+
For strings:
1413

1514
```php
1615
v::containsAny(['lorem', 'dolor'])->assert('lorem ipsum');
1716
// Validation passes successfully
1817
```
1918

20-
For arrays (comparing is case sensitive to respect "contains" behavior):
19+
For arrays:
2120

2221
```php
2322
v::containsAny(['lorem', 'dolor'])->assert(['ipsum', 'lorem']);
2423
// Validation passes successfully
2524
```
2625

27-
A second parameter may be passed for identical comparison instead
28-
of equal comparison for arrays.
29-
3026
Message template for this validator includes `{{needles}}`.
3127

3228
## Templates
@@ -52,9 +48,10 @@ Message template for this validator includes `{{needles}}`.
5248

5349
## Changelog
5450

55-
| Version | Description |
56-
| ------: | :---------- |
57-
| 2.0.0 | Created |
51+
| Version | Description |
52+
| ------: | :---------------------------------- |
53+
| 3.0.0 | Case-insensitive comparison removed |
54+
| 2.0.0 | Created |
5855

5956
## See Also
6057

docs/validators/ContainsCount.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ SPDX-License-Identifier: MIT
66
# ContainsCount
77

88
- `ContainsCount(mixed $containsValue, int $count)`
9-
- `ContainsCount(mixed $containsValue, int $count, bool $identical)`
109

1110
Validates if the input contains a value a specific number of times.
1211

@@ -24,8 +23,6 @@ v::containsCount('ipsum', 2)->assert(['ipsum', 'lorem', 'ipsum']);
2423
// Validation passes successfully
2524
```
2625

27-
A third parameter may be passed for identical comparison instead of equal comparison.
28-
2926
```php
3027
v::containsCount(1, 1, true)->assert([1, 2, 3]);
3128
// Validation passes successfully

docs/validators/EndsWith.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ SPDX-License-Identifier: MIT
66
# EndsWith
77

88
- `EndsWith(mixed $endValue)`
9-
- `EndsWith(mixed $endValue, bool $identical)`
109

1110
This validator is similar to `Contains()`, but validates
1211
only if the value is at the end of the input.
@@ -25,9 +24,6 @@ v::endsWith('ipsum')->assert(['lorem', 'ipsum']);
2524
// Validation passes successfully
2625
```
2726

28-
A second parameter may be passed for identical comparison instead
29-
of equal comparison.
30-
3127
Message template for this validator includes `{{endValue}}`.
3228

3329
## Templates
@@ -53,9 +49,10 @@ Message template for this validator includes `{{endValue}}`.
5349

5450
## Changelog
5551

56-
| Version | Description |
57-
| ------: | :---------- |
58-
| 0.3.9 | Created |
52+
| Version | Description |
53+
| ------: | :---------------------------------- |
54+
| 3.0.0 | Case-insensitive comparison removed |
55+
| 0.3.9 | Created |
5956

6057
## See Also
6158

docs/validators/In.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ SPDX-License-Identifier: MIT
66
# In
77

88
- `In(mixed $haystack)`
9-
- `In(mixed $haystack, bool $compareIdentical)`
109

1110
Validates if the input is contained in a specific haystack.
1211

@@ -24,9 +23,6 @@ v::in(['lorem', 'ipsum'])->assert('lorem');
2423
// Validation passes successfully
2524
```
2625

27-
A second parameter may be passed for identical comparison instead
28-
of equal comparison.
29-
3026
Message template for this validator includes `{{haystack}}`.
3127

3228
## Templates
@@ -53,9 +49,10 @@ Message template for this validator includes `{{haystack}}`.
5349

5450
## Changelog
5551

56-
| Version | Description |
57-
| ------: | :---------- |
58-
| 0.3.9 | Created |
52+
| Version | Description |
53+
| ------: | :---------------------------------- |
54+
| 3.0.0 | Case-insensitive comparison removed |
55+
| 0.3.9 | Created |
5956

6057
## See Also
6158

docs/validators/StartsWith.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ SPDX-License-Identifier: MIT
66
# StartsWith
77

88
- `StartsWith(mixed $startValue)`
9-
- `StartsWith(mixed $startValue, bool $identical)`
109

1110
Validates whether the input starts with a given value.
1211

@@ -27,9 +26,6 @@ v::startsWith('lorem')->assert(['lorem', 'ipsum']);
2726
// Validation passes successfully
2827
```
2928

30-
`true` may be passed as a parameter to indicate identical comparison
31-
instead of equal.
32-
3329
Message template for this validator includes `{{startValue}}`.
3430

3531
## Templates
@@ -55,9 +51,10 @@ Message template for this validator includes `{{startValue}}`.
5551

5652
## Changelog
5753

58-
| Version | Description |
59-
| ------: | :---------- |
60-
| 0.3.9 | Created |
54+
| Version | Description |
55+
| ------: | :---------------------------------- |
56+
| 3.0.0 | Case-insensitive comparison removed |
57+
| 0.3.9 | Created |
6158

6259
## See Also
6360

src/Mixins/AllBuilder.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,12 @@ public static function allCnpj(): Chain;
6464

6565
public static function allConsonant(string ...$additionalChars): Chain;
6666

67-
public static function allContains(mixed $containsValue, bool $identical = false): Chain;
67+
public static function allContains(mixed $containsValue): Chain;
6868

6969
/** @param non-empty-array<mixed> $needles */
70-
public static function allContainsAny(array $needles, bool $identical = false): Chain;
70+
public static function allContainsAny(array $needles): Chain;
7171

72-
public static function allContainsCount(mixed $containsValue, int $count, bool $identical = false): Chain;
72+
public static function allContainsCount(mixed $containsValue, int $count): Chain;
7373

7474
public static function allControl(string ...$additionalChars): Chain;
7575

@@ -106,7 +106,7 @@ public static function allEmail(): Chain;
106106

107107
public static function allEmoji(): Chain;
108108

109-
public static function allEndsWith(mixed $endValue, bool $identical = false): Chain;
109+
public static function allEndsWith(mixed $endValue): Chain;
110110

111111
public static function allEquals(mixed $compareTo): Chain;
112112

@@ -154,7 +154,7 @@ public static function allImage(): Chain;
154154

155155
public static function allImei(): Chain;
156156

157-
public static function allIn(mixed $haystack, bool $compareIdentical = false): Chain;
157+
public static function allIn(mixed $haystack): Chain;
158158

159159
public static function allInfinite(): Chain;
160160

@@ -276,7 +276,7 @@ public static function allSpace(string ...$additionalChars): Chain;
276276

277277
public static function allSpaced(): Chain;
278278

279-
public static function allStartsWith(mixed $startValue, bool $identical = false): Chain;
279+
public static function allStartsWith(mixed $startValue): Chain;
280280

281281
public static function allStringType(): Chain;
282282

src/Mixins/AllChain.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,12 @@ public function allCnpj(): Chain;
6464

6565
public function allConsonant(string ...$additionalChars): Chain;
6666

67-
public function allContains(mixed $containsValue, bool $identical = false): Chain;
67+
public function allContains(mixed $containsValue): Chain;
6868

6969
/** @param non-empty-array<mixed> $needles */
70-
public function allContainsAny(array $needles, bool $identical = false): Chain;
70+
public function allContainsAny(array $needles): Chain;
7171

72-
public function allContainsCount(mixed $containsValue, int $count, bool $identical = false): Chain;
72+
public function allContainsCount(mixed $containsValue, int $count): Chain;
7373

7474
public function allControl(string ...$additionalChars): Chain;
7575

@@ -106,7 +106,7 @@ public function allEmail(): Chain;
106106

107107
public function allEmoji(): Chain;
108108

109-
public function allEndsWith(mixed $endValue, bool $identical = false): Chain;
109+
public function allEndsWith(mixed $endValue): Chain;
110110

111111
public function allEquals(mixed $compareTo): Chain;
112112

@@ -154,7 +154,7 @@ public function allImage(): Chain;
154154

155155
public function allImei(): Chain;
156156

157-
public function allIn(mixed $haystack, bool $compareIdentical = false): Chain;
157+
public function allIn(mixed $haystack): Chain;
158158

159159
public function allInfinite(): Chain;
160160

@@ -276,7 +276,7 @@ public function allSpace(string ...$additionalChars): Chain;
276276

277277
public function allSpaced(): Chain;
278278

279-
public function allStartsWith(mixed $startValue, bool $identical = false): Chain;
279+
public function allStartsWith(mixed $startValue): Chain;
280280

281281
public function allStringType(): Chain;
282282

0 commit comments

Comments
 (0)