Failed Conditions
Pull Request — master (#200)
by
unknown
03:00
created

src/Assert.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
 * This file is part of the webmozart/assert package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Webmozart\Assert;
13
14
use ArrayAccess;
15
use BadMethodCallException;
16
use Closure;
17
use Countable;
18
use DateTime;
19
use DateTimeImmutable;
20
use Exception;
21
use InvalidArgumentException;
22
use ResourceBundle;
23
use SimpleXMLElement;
24
use Throwable;
25
use Traversable;
26
27
/**
28
 * Efficient assertions to validate the input/output of your methods.
29
 *
30
 * @method static void nullOrString($value, $message = '')
31
 * @method static void nullOrStringNotEmpty($value, $message = '')
32
 * @method static void nullOrInteger($value, $message = '')
33
 * @method static void nullOrIntegerish($value, $message = '')
34
 * @method static void nullOrFloat($value, $message = '')
35
 * @method static void nullOrNumeric($value, $message = '')
36
 * @method static void nullOrNatural($value, $message = '')
37
 * @method static void nullOrBoolean($value, $message = '')
38
 * @method static void nullOrScalar($value, $message = '')
39
 * @method static void nullOrObject($value, $message = '')
40
 * @method static void nullOrResource($value, $type = null, $message = '')
41
 * @method static void nullOrIsCallable($value, $message = '')
42
 * @method static void nullOrIsArray($value, $message = '')
43
 * @method static void nullOrIsTraversable($value, $message = '')
44
 * @method static void nullOrIsArrayAccessible($value, $message = '')
45
 * @method static void nullOrIsCountable($value, $message = '')
46
 * @method static void nullOrIsIterable($value, $message = '')
47
 * @method static void nullOrIsInstanceOf($value, $class, $message = '')
48
 * @method static void nullOrNotInstanceOf($value, $class, $message = '')
49
 * @method static void nullOrIsInstanceOfAny($value, $classes, $message = '')
50
 * @method static void nullOrIsAOf($value, $classes, $message = '')
51
 * @method static void nullOrIsAnyOf($value, $classes, $message = '')
52
 * @method static void nullOrIsNotA($value, $classes, $message = '')
53
 * @method static void nullOrIsEmpty($value, $message = '')
54
 * @method static void nullOrNotEmpty($value, $message = '')
55
 * @method static void nullOrTrue($value, $message = '')
56
 * @method static void nullOrFalse($value, $message = '')
57
 * @method static void nullOrNotFalse($value, $message = '')
58
 * @method static void nullOrIp($value, $message = '')
59
 * @method static void nullOrIpv4($value, $message = '')
60
 * @method static void nullOrIpv6($value, $message = '')
61
 * @method static void nullOrEmail($value, $message = '')
62
 * @method static void nullOrUniqueValues($values, $message = '')
63
 * @method static void nullOrEq($value, $expect, $message = '')
64
 * @method static void nullOrNotEq($value, $expect, $message = '')
65
 * @method static void nullOrSame($value, $expect, $message = '')
66
 * @method static void nullOrNotSame($value, $expect, $message = '')
67
 * @method static void nullOrGreaterThan($value, $limit, $message = '')
68
 * @method static void nullOrGreaterThanEq($value, $limit, $message = '')
69
 * @method static void nullOrLessThan($value, $limit, $message = '')
70
 * @method static void nullOrLessThanEq($value, $limit, $message = '')
71
 * @method static void nullOrRange($value, $min, $max, $message = '')
72
 * @method static void nullOrOneOf($value, $values, $message = '')
73
 * @method static void nullOrInArray($value, $values, $message = '')
74
 * @method static void nullOrContains($value, $subString, $message = '')
75
 * @method static void nullOrNotContains($value, $subString, $message = '')
76
 * @method static void nullOrNotWhitespaceOnly($value, $message = '')
77
 * @method static void nullOrStartsWith($value, $prefix, $message = '')
78
 * @method static void nullOrNotStartsWith($value, $prefix, $message = '')
79
 * @method static void nullOrStartsWithLetter($value, $message = '')
80
 * @method static void nullOrEndsWith($value, $suffix, $message = '')
81
 * @method static void nullOrNotEndsWith($value, $suffix, $message = '')
82
 * @method static void nullOrRegex($value, $pattern, $message = '')
83
 * @method static void nullOrNotRegex($value, $pattern, $message = '')
84
 * @method static void nullOrUnicodeLetters($value, $message = '')
85
 * @method static void nullOrAlpha($value, $message = '')
86
 * @method static void nullOrDigits($value, $message = '')
87
 * @method static void nullOrAlnum($value, $message = '')
88
 * @method static void nullOrLower($value, $message = '')
89
 * @method static void nullOrUpper($value, $message = '')
90
 * @method static void nullOrLength($value, $length, $message = '')
91
 * @method static void nullOrMinLength($value, $min, $message = '')
92
 * @method static void nullOrMaxLength($value, $max, $message = '')
93
 * @method static void nullOrLengthBetween($value, $min, $max, $message = '')
94
 * @method static void nullOrFileExists($value, $message = '')
95
 * @method static void nullOrFile($value, $message = '')
96
 * @method static void nullOrDirectory($value, $message = '')
97
 * @method static void nullOrReadable($value, $message = '')
98
 * @method static void nullOrWritable($value, $message = '')
99
 * @method static void nullOrClassExists($value, $message = '')
100
 * @method static void nullOrSubclassOf($value, $class, $message = '')
101
 * @method static void nullOrInterfaceExists($value, $message = '')
102
 * @method static void nullOrImplementsInterface($value, $interface, $message = '')
103
 * @method static void nullOrPropertyExists($value, $property, $message = '')
104
 * @method static void nullOrPropertyNotExists($value, $property, $message = '')
105
 * @method static void nullOrMethodExists($value, $method, $message = '')
106
 * @method static void nullOrMethodNotExists($value, $method, $message = '')
107
 * @method static void nullOrKeyExists($value, $key, $message = '')
108
 * @method static void nullOrKeyNotExists($value, $key, $message = '')
109
 * @method static void nullOrValidArrayKey($value, $message = '')
110
 * @method static void nullOrCount($value, $key, $message = '')
111
 * @method static void nullOrMinCount($value, $min, $message = '')
112
 * @method static void nullOrMaxCount($value, $max, $message = '')
113
 * @method static void nullOrIsList($value, $message = '')
114
 * @method static void nullOrIsNonEmptyList($value, $message = '')
115
 * @method static void nullOrIsMap($value, $message = '')
116
 * @method static void nullOrIsNonEmptyMap($value, $message = '')
117
 * @method static void nullOrCountBetween($value, $min, $max, $message = '')
118
 * @method static void nullOrUuid($values, $message = '')
119
 * @method static void nullOrThrows($expression, $class = 'Exception', $message = '')
120
 * @method static void allString($values, $message = '')
121
 * @method static void allStringNotEmpty($values, $message = '')
122
 * @method static void allInteger($values, $message = '')
123
 * @method static void allIntegerish($values, $message = '')
124
 * @method static void allFloat($values, $message = '')
125
 * @method static void allNumeric($values, $message = '')
126
 * @method static void allNatural($values, $message = '')
127
 * @method static void allBoolean($values, $message = '')
128
 * @method static void allScalar($values, $message = '')
129
 * @method static void allObject($values, $message = '')
130
 * @method static void allResource($values, $type = null, $message = '')
131
 * @method static void allIsCallable($values, $message = '')
132
 * @method static void allIsArray($values, $message = '')
133
 * @method static void allIsTraversable($values, $message = '')
134
 * @method static void allIsArrayAccessible($values, $message = '')
135
 * @method static void allIsCountable($values, $message = '')
136
 * @method static void allIsIterable($values, $message = '')
137
 * @method static void allIsInstanceOf($values, $class, $message = '')
138
 * @method static void allNotInstanceOf($values, $class, $message = '')
139
 * @method static void allIsInstanceOfAny($values, $classes, $message = '')
140
 * @method static void allIsAOf($values, $class, $message = '')
141
 * @method static void allIsAnyOf($values, $class, $message = '')
142
 * @method static void allIsNotA($values, $class, $message = '')
143
 * @method static void allNull($values, $message = '')
144
 * @method static void allNotNull($values, $message = '')
145
 * @method static void allIsEmpty($values, $message = '')
146
 * @method static void allNotEmpty($values, $message = '')
147
 * @method static void allTrue($values, $message = '')
148
 * @method static void allFalse($values, $message = '')
149
 * @method static void allNotFalse($values, $message = '')
150
 * @method static void allIp($values, $message = '')
151
 * @method static void allIpv4($values, $message = '')
152
 * @method static void allIpv6($values, $message = '')
153
 * @method static void allEmail($values, $message = '')
154
 * @method static void allUniqueValues($values, $message = '')
155
 * @method static void allEq($values, $expect, $message = '')
156
 * @method static void allNotEq($values, $expect, $message = '')
157
 * @method static void allSame($values, $expect, $message = '')
158
 * @method static void allNotSame($values, $expect, $message = '')
159
 * @method static void allGreaterThan($values, $limit, $message = '')
160
 * @method static void allGreaterThanEq($values, $limit, $message = '')
161
 * @method static void allLessThan($values, $limit, $message = '')
162
 * @method static void allLessThanEq($values, $limit, $message = '')
163
 * @method static void allRange($values, $min, $max, $message = '')
164
 * @method static void allOneOf($values, $values, $message = '')
165
 * @method static void allInArray($values, $values, $message = '')
166
 * @method static void allContains($values, $subString, $message = '')
167
 * @method static void allNotContains($values, $subString, $message = '')
168
 * @method static void allNotWhitespaceOnly($values, $message = '')
169
 * @method static void allStartsWith($values, $prefix, $message = '')
170
 * @method static void allNotStartsWith($values, $prefix, $message = '')
171
 * @method static void allStartsWithLetter($values, $message = '')
172
 * @method static void allEndsWith($values, $suffix, $message = '')
173
 * @method static void allNotEndsWith($values, $suffix, $message = '')
174
 * @method static void allRegex($values, $pattern, $message = '')
175
 * @method static void allNotRegex($values, $pattern, $message = '')
176
 * @method static void allUnicodeLetters($values, $message = '')
177
 * @method static void allAlpha($values, $message = '')
178
 * @method static void allDigits($values, $message = '')
179
 * @method static void allAlnum($values, $message = '')
180
 * @method static void allLower($values, $message = '')
181
 * @method static void allUpper($values, $message = '')
182
 * @method static void allLength($values, $length, $message = '')
183
 * @method static void allMinLength($values, $min, $message = '')
184
 * @method static void allMaxLength($values, $max, $message = '')
185
 * @method static void allLengthBetween($values, $min, $max, $message = '')
186
 * @method static void allFileExists($values, $message = '')
187
 * @method static void allFile($values, $message = '')
188
 * @method static void allDirectory($values, $message = '')
189
 * @method static void allReadable($values, $message = '')
190
 * @method static void allWritable($values, $message = '')
191
 * @method static void allClassExists($values, $message = '')
192
 * @method static void allSubclassOf($values, $class, $message = '')
193
 * @method static void allInterfaceExists($values, $message = '')
194
 * @method static void allImplementsInterface($values, $interface, $message = '')
195
 * @method static void allPropertyExists($values, $property, $message = '')
196
 * @method static void allPropertyNotExists($values, $property, $message = '')
197
 * @method static void allMethodExists($values, $method, $message = '')
198
 * @method static void allMethodNotExists($values, $method, $message = '')
199
 * @method static void allKeyExists($values, $key, $message = '')
200
 * @method static void allKeyNotExists($values, $key, $message = '')
201
 * @method static void allValidArrayKey($values, $message = '')
202
 * @method static void allCount($values, $key, $message = '')
203
 * @method static void allMinCount($values, $min, $message = '')
204
 * @method static void allMaxCount($values, $max, $message = '')
205
 * @method static void allCountBetween($values, $min, $max, $message = '')
206
 * @method static void allIsList($values, $message = '')
207
 * @method static void allIsNonEmptyList($values, $message = '')
208
 * @method static void allIsMap($values, $message = '')
209
 * @method static void allIsNonEmptyMap($values, $message = '')
210
 * @method static void allUuid($values, $message = '')
211
 * @method static void allThrows($expressions, $class = 'Exception', $message = '')
212
 *
213
 * @since  1.0
214
 *
215
 * @author Bernhard Schussek <[email protected]>
216
 */
217
class Assert
218
{
219
    /**
220
     * @psalm-pure
221
     * @psalm-assert string $value
222
     *
223
     * @param mixed  $value
224
     * @param string $message
225
     *
226
     * @throws InvalidArgumentException
227
     */
228 241
    public static function string($value, $message = '')
229
    {
230 241
        if (!\is_string($value)) {
231 45
            static::reportInvalidArgument(\sprintf(
232 45
                $message ?: 'Expected a string. Got: %s',
233 45
                static::typeToString($value)
234
            ));
235
        }
236 196
    }
237
238
    /**
239
     * @psalm-pure
240
     * @psalm-assert string $value
241
     * @psalm-assert !empty $value
242
     *
243
     * @param mixed  $value
244
     * @param string $message
245
     *
246
     * @throws InvalidArgumentException
247
     */
248 16
    public static function stringNotEmpty($value, $message = '')
249
    {
250 16
        static::string($value, $message);
251 12
        static::notEq($value, '', $message);
252 8
    }
253
254
    /**
255
     * @psalm-pure
256
     * @psalm-assert int $value
257
     *
258
     * @param mixed  $value
259
     * @param string $message
260
     *
261
     * @throws InvalidArgumentException
262
     */
263 17
    public static function integer($value, $message = '')
264
    {
265 17
        if (!\is_int($value)) {
266 13
            static::reportInvalidArgument(\sprintf(
267 13
                $message ?: 'Expected an integer. Got: %s',
268 13
                static::typeToString($value)
269
            ));
270
        }
271 4
    }
272
273
    /**
274
     * @psalm-pure
275
     * @psalm-assert numeric $value
276
     *
277
     * @param mixed  $value
278
     * @param string $message
279
     *
280
     * @throws InvalidArgumentException
281
     */
282 16
    public static function integerish($value, $message = '')
283
    {
284 16
        if (!\is_numeric($value) || $value != (int) $value) {
285 4
            static::reportInvalidArgument(\sprintf(
286 4
                $message ?: 'Expected an integerish value. Got: %s',
287 4
                static::typeToString($value)
288
            ));
289
        }
290 12
    }
291
292
    /**
293
     * @psalm-pure
294
     * @psalm-assert float $value
295
     *
296
     * @param mixed  $value
297
     * @param string $message
298
     *
299
     * @throws InvalidArgumentException
300
     */
301 16
    public static function float($value, $message = '')
302
    {
303 16
        if (!\is_float($value)) {
304 8
            static::reportInvalidArgument(\sprintf(
305 8
                $message ?: 'Expected a float. Got: %s',
306 8
                static::typeToString($value)
307
            ));
308
        }
309 8
    }
310
311
    /**
312
     * @psalm-pure
313
     * @psalm-assert numeric $value
314
     *
315
     * @param mixed  $value
316
     * @param string $message
317
     *
318
     * @throws InvalidArgumentException
319
     */
320 20
    public static function numeric($value, $message = '')
321
    {
322 20
        if (!\is_numeric($value)) {
323 4
            static::reportInvalidArgument(\sprintf(
324 4
                $message ?: 'Expected a numeric. Got: %s',
325 4
                static::typeToString($value)
326
            ));
327
        }
328 16
    }
329
330
    /**
331
     * @psalm-pure
332
     * @psalm-assert int $value
333
     *
334
     * @param mixed  $value
335
     * @param string $message
336
     *
337
     * @throws InvalidArgumentException
338
     */
339 24
    public static function natural($value, $message = '')
340
    {
341 24
        if (!\is_int($value) || $value < 0) {
342 16
            static::reportInvalidArgument(\sprintf(
343 16
                $message ?: 'Expected a non-negative integer. Got: %s',
344 16
                static::valueToString($value)
345
            ));
346
        }
347 8
    }
348
349
    /**
350
     * @psalm-pure
351
     * @psalm-assert bool $value
352
     *
353
     * @param mixed  $value
354
     * @param string $message
355
     *
356
     * @throws InvalidArgumentException
357
     */
358 16
    public static function boolean($value, $message = '')
359
    {
360 16
        if (!\is_bool($value)) {
361 8
            static::reportInvalidArgument(\sprintf(
362 8
                $message ?: 'Expected a boolean. Got: %s',
363 8
                static::typeToString($value)
364
            ));
365
        }
366 8
    }
367
368
    /**
369
     * @psalm-pure
370
     * @psalm-assert scalar $value
371
     *
372
     * @param mixed  $value
373
     * @param string $message
374
     *
375
     * @throws InvalidArgumentException
376
     */
377 23
    public static function scalar($value, $message = '')
378
    {
379 23
        if (!\is_scalar($value)) {
380 11
            static::reportInvalidArgument(\sprintf(
381 11
                $message ?: 'Expected a scalar. Got: %s',
382 11
                static::typeToString($value)
383
            ));
384
        }
385 12
    }
386
387
    /**
388
     * @psalm-pure
389
     * @psalm-assert object $value
390
     *
391
     * @param mixed  $value
392
     * @param string $message
393
     *
394
     * @throws InvalidArgumentException
395
     */
396 23
    public static function object($value, $message = '')
397
    {
398 23
        if (!\is_object($value)) {
399 15
            static::reportInvalidArgument(\sprintf(
400 15
                $message ?: 'Expected an object. Got: %s',
401 15
                static::typeToString($value)
402
            ));
403
        }
404 8
    }
405
406
    /**
407
     * @psalm-pure
408
     * @psalm-assert resource $value
409
     *
410
     * @param mixed       $value
411
     * @param string|null $type    type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php
412
     * @param string      $message
413
     *
414
     * @throws InvalidArgumentException
415
     */
416 16
    public static function resource($value, $type = null, $message = '')
417
    {
418 16
        if (!\is_resource($value)) {
419 4
            static::reportInvalidArgument(\sprintf(
420 4
                $message ?: 'Expected a resource. Got: %s',
421 4
                static::typeToString($value)
422
            ));
423
        }
424
425 12
        if ($type && $type !== \get_resource_type($value)) {
426 4
            static::reportInvalidArgument(\sprintf(
427 4
                $message ?: 'Expected a resource of type %2$s. Got: %s',
428 4
                static::typeToString($value),
429 4
                $type
430
            ));
431
        }
432 8
    }
433
434
    /**
435
     * @psalm-pure
436
     * @psalm-assert callable $value
437
     *
438
     * @param mixed  $value
439
     * @param string $message
440
     *
441
     * @throws InvalidArgumentException
442
     */
443 20
    public static function isCallable($value, $message = '')
444
    {
445 20
        if (!\is_callable($value)) {
446 8
            static::reportInvalidArgument(\sprintf(
447 8
                $message ?: 'Expected a callable. Got: %s',
448 8
                static::typeToString($value)
449
            ));
450
        }
451 12
    }
452
453
    /**
454
     * @psalm-pure
455
     * @psalm-assert array $value
456
     *
457
     * @param mixed  $value
458
     * @param string $message
459
     *
460
     * @throws InvalidArgumentException
461
     */
462 20
    public static function isArray($value, $message = '')
463
    {
464 20
        if (!\is_array($value)) {
465 12
            static::reportInvalidArgument(\sprintf(
466 12
                $message ?: 'Expected an array. Got: %s',
467 12
                static::typeToString($value)
468
            ));
469
        }
470 8
    }
471
472
    /**
473
     * @psalm-pure
474
     * @psalm-assert iterable $value
475
     *
476
     * @deprecated use "isIterable" or "isInstanceOf" instead
477
     *
478
     * @param mixed  $value
479
     * @param string $message
480
     *
481
     * @throws InvalidArgumentException
482
     */
483 20
    public static function isTraversable($value, $message = '')
484
    {
485 20
        @\trigger_error(
486 20
            \sprintf(
487 20
                'The "%s" assertion is deprecated. You should stop using it, as it will soon be removed in 2.0 version. Use "isIterable" or "isInstanceOf" instead.',
488 20
                __METHOD__
489
            ),
490 20
            \E_USER_DEPRECATED
491
        );
492
493 20
        if (!\is_array($value) && !($value instanceof Traversable)) {
494 8
            static::reportInvalidArgument(\sprintf(
495 8
                $message ?: 'Expected a traversable. Got: %s',
496 8
                static::typeToString($value)
497
            ));
498
        }
499 12
    }
500
501
    /**
502
     * @psalm-pure
503
     * @psalm-assert array|ArrayAccess $value
504
     *
505
     * @param mixed  $value
506
     * @param string $message
507
     *
508
     * @throws InvalidArgumentException
509
     */
510 20 View Code Duplication
    public static function isArrayAccessible($value, $message = '')
511
    {
512 20
        if (!\is_array($value) && !($value instanceof ArrayAccess)) {
513 8
            static::reportInvalidArgument(\sprintf(
514 8
                $message ?: 'Expected an array accessible. Got: %s',
515 8
                static::typeToString($value)
516
            ));
517
        }
518 12
    }
519
520
    /**
521
     * @psalm-pure
522
     * @psalm-assert countable $value
523
     *
524
     * @param mixed  $value
525
     * @param string $message
526
     *
527
     * @throws InvalidArgumentException
528
     */
529 28
    public static function isCountable($value, $message = '')
530
    {
531
        if (
532 28
            !\is_array($value)
533 28
            && !($value instanceof Countable)
534 28
            && !(extension_loaded('intl') && $value instanceof ResourceBundle)
0 ignored issues
show
The class ResourceBundle does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
535 28
            && !(extension_loaded('SimpleXML') && $value instanceof SimpleXMLElement)
536
        ) {
537 12
            static::reportInvalidArgument(\sprintf(
538 12
                $message ?: 'Expected a countable. Got: %s',
539 12
                static::typeToString($value)
540
            ));
541
        }
542 16
    }
543
544
    /**
545
     * @psalm-pure
546
     * @psalm-assert iterable $value
547
     *
548
     * @param mixed  $value
549
     * @param string $message
550
     *
551
     * @throws InvalidArgumentException
552
     */
553 1044 View Code Duplication
    public static function isIterable($value, $message = '')
554
    {
555 1044
        if (!\is_array($value) && !($value instanceof Traversable)) {
556 8
            static::reportInvalidArgument(\sprintf(
557 8
                $message ?: 'Expected an iterable. Got: %s',
558 8
                static::typeToString($value)
559
            ));
560
        }
561 1040
    }
562
563
    /**
564
     * @psalm-pure
565
     * @psalm-template ExpectedType of object
566
     * @psalm-param class-string<ExpectedType> $class
567
     * @psalm-assert ExpectedType $value
568
     *
569
     * @param mixed         $value
570
     * @param string|object $class
571
     * @param string        $message
572
     *
573
     * @throws InvalidArgumentException
574
     */
575 19
    public static function isInstanceOf($value, $class, $message = '')
576
    {
577 19
        if (!($value instanceof $class)) {
578 15
            static::reportInvalidArgument(\sprintf(
579 15
                $message ?: 'Expected an instance of %2$s. Got: %s',
580 15
                static::typeToString($value),
581 15
                $class
582
            ));
583
        }
584 4
    }
585
586
    /**
587
     * @psalm-pure
588
     * @psalm-template ExpectedType of object
589
     * @psalm-param class-string<ExpectedType> $class
590
     * @psalm-assert !ExpectedType $value
591
     *
592
     * @param mixed         $value
593
     * @param string|object $class
594
     * @param string        $message
595
     *
596
     * @throws InvalidArgumentException
597
     */
598 16
    public static function notInstanceOf($value, $class, $message = '')
599
    {
600 16
        if ($value instanceof $class) {
601 4
            static::reportInvalidArgument(\sprintf(
602 4
                $message ?: 'Expected an instance other than %2$s. Got: %s',
603 4
                static::typeToString($value),
604 4
                $class
605
            ));
606
        }
607 12
    }
608
609
    /**
610
     * @psalm-pure
611
     * @psalm-param array<class-string> $classes
612
     *
613
     * @param mixed                $value
614
     * @param array<object|string> $classes
615
     * @param string               $message
616
     *
617
     * @throws InvalidArgumentException
618
     */
619 20
    public static function isInstanceOfAny($value, array $classes, $message = '')
620
    {
621 20
        foreach ($classes as $class) {
622 20
            if ($value instanceof $class) {
623 8
                return;
624
            }
625
        }
626
627 12
        static::reportInvalidArgument(\sprintf(
628 12
            $message ?: 'Expected an instance of any of %2$s. Got: %s',
629 12
            static::typeToString($value),
630 12
            \implode(', ', \array_map(array('static', 'valueToString'), $classes))
631
        ));
632
    }
633
634
    /**
635
     * @psalm-pure
636
     * @psalm-template ExpectedType of object
637
     * @psalm-param class-string<ExpectedType> $class
638
     * @psalm-assert ExpectedType|class-string<ExpectedType> $value
639
     *
640
     * @param object|string $value
641
     * @param string        $class
642
     * @param string        $message
643
     *
644
     * @throws InvalidArgumentException
645
     */
646 20 View Code Duplication
    public static function isAOf($value, $class, $message = '')
647
    {
648 20
        static::string($class, 'Expected class as a string. Got: %s');
649
650 16
        if (!\is_a($value, $class, \is_string($value))) {
651 12
            static::reportInvalidArgument(sprintf(
652 12
                $message ?: 'Expected an instance of this class or to this class among his parents %2$s. Got: %s',
653 12
                static::typeToString($value),
654
                $class
655
            ));
656
        }
657 4
    }
658
659
    /**
660
     * @psalm-pure
661
     * @psalm-template UnexpectedType of object
662
     * @psalm-param class-string<UnexpectedType> $class
663
     * @psalm-assert !UnexpectedType $value
664
     * @psalm-assert !class-string<UnexpectedType> $value
665
     *
666
     * @param object|string $value
667
     * @param string        $class
668
     * @param string        $message
669
     *
670
     * @throws InvalidArgumentException
671
     */
672 20 View Code Duplication
    public static function isNotA($value, $class, $message = '')
673
    {
674 20
        static::string($class, 'Expected class as a string. Got: %s');
675
676 16
        if (\is_a($value, $class, \is_string($value))) {
677 4
            static::reportInvalidArgument(sprintf(
678 4
                $message ?: 'Expected an instance of this class or to this class among his parents other than %2$s. Got: %s',
679 4
                static::typeToString($value),
680
                $class
681
            ));
682
        }
683 12
    }
684
685
    /**
686
     * @psalm-pure
687
     * @psalm-param array<class-string> $classes
688
     *
689
     * @param object|string $value
690
     * @param string[]      $classes
691
     * @param string        $message
692
     *
693
     * @throws InvalidArgumentException
694
     */
695 24
    public static function isAnyOf($value, array $classes, $message = '')
696
    {
697 24
        foreach ($classes as $class) {
698 24
            static::string($class, 'Expected class as a string. Got: %s');
699
700 20
            if (\is_a($value, $class, \is_string($value))) {
701 8
                return;
702
            }
703
        }
704
705 12
        static::reportInvalidArgument(sprintf(
706 12
            $message ?: 'Expected an any of instance of this class or to this class among his parents other than %2$s. Got: %s',
707 12
            static::typeToString($value),
708 12
            \implode(', ', \array_map(array('static', 'valueToString'), $classes))
709
        ));
710
    }
711
712
    /**
713
     * @psalm-pure
714
     * @psalm-assert empty $value
715
     *
716
     * @param mixed  $value
717
     * @param string $message
718
     *
719
     * @throws InvalidArgumentException
720
     */
721 23
    public static function isEmpty($value, $message = '')
722
    {
723 23
        if (!empty($value)) {
724 8
            static::reportInvalidArgument(\sprintf(
725 8
                $message ?: 'Expected an empty value. Got: %s',
726 8
                static::valueToString($value)
727
            ));
728
        }
729 15
    }
730
731
    /**
732
     * @psalm-pure
733
     * @psalm-assert !empty $value
734
     *
735
     * @param mixed  $value
736
     * @param string $message
737
     *
738
     * @throws InvalidArgumentException
739
     */
740 55
    public static function notEmpty($value, $message = '')
741
    {
742 55
        if (empty($value)) {
743 23
            static::reportInvalidArgument(\sprintf(
744 23
                $message ?: 'Expected a non-empty value. Got: %s',
745 23
                static::valueToString($value)
746
            ));
747
        }
748 32
    }
749
750
    /**
751
     * @psalm-pure
752
     * @psalm-assert null $value
753
     *
754
     * @param mixed  $value
755
     * @param string $message
756
     *
757
     * @throws InvalidArgumentException
758
     */
759 11
    public static function null($value, $message = '')
760
    {
761 11
        if (null !== $value) {
762 8
            static::reportInvalidArgument(\sprintf(
763 8
                $message ?: 'Expected null. Got: %s',
764 8
                static::valueToString($value)
765
            ));
766
        }
767 3
    }
768
769
    /**
770
     * @psalm-pure
771
     * @psalm-assert !null $value
772
     *
773
     * @param mixed  $value
774
     * @param string $message
775
     *
776
     * @throws InvalidArgumentException
777
     */
778 11
    public static function notNull($value, $message = '')
779
    {
780 11
        if (null === $value) {
781 3
            static::reportInvalidArgument(
782 3
                $message ?: 'Expected a value other than null.'
783
            );
784
        }
785 8
    }
786
787
    /**
788
     * @psalm-pure
789
     * @psalm-assert true $value
790
     *
791
     * @param mixed  $value
792
     * @param string $message
793
     *
794
     * @throws InvalidArgumentException
795
     */
796 15
    public static function true($value, $message = '')
797
    {
798 15
        if (true !== $value) {
799 11
            static::reportInvalidArgument(\sprintf(
800 11
                $message ?: 'Expected a value to be true. Got: %s',
801 11
                static::valueToString($value)
802
            ));
803
        }
804 4
    }
805
806
    /**
807
     * @psalm-pure
808
     * @psalm-assert false $value
809
     *
810
     * @param mixed  $value
811
     * @param string $message
812
     *
813
     * @throws InvalidArgumentException
814
     */
815 19
    public static function false($value, $message = '')
816
    {
817 19
        if (false !== $value) {
818 15
            static::reportInvalidArgument(\sprintf(
819 15
                $message ?: 'Expected a value to be false. Got: %s',
820 15
                static::valueToString($value)
821
            ));
822
        }
823 4
    }
824
825
    /**
826
     * @psalm-pure
827
     * @psalm-assert !false $value
828
     *
829
     * @param mixed  $value
830
     * @param string $message
831
     *
832
     * @throws InvalidArgumentException
833
     */
834 19
    public static function notFalse($value, $message = '')
835
    {
836 19
        if (false === $value) {
837 4
            static::reportInvalidArgument(
838 4
                $message ?: 'Expected a value other than false.'
839
            );
840
        }
841 15
    }
842
843
    /**
844
     * @param mixed  $value
845
     * @param string $message
846
     *
847
     * @throws InvalidArgumentException
848
     */
849 51 View Code Duplication
    public static function ip($value, $message = '')
850
    {
851 51
        if (false === \filter_var($value, \FILTER_VALIDATE_IP)) {
852 19
            static::reportInvalidArgument(\sprintf(
853 19
                $message ?: 'Expected a value to be an IP. Got: %s',
854 19
                static::valueToString($value)
855
            ));
856
        }
857 32
    }
858
859
    /**
860
     * @param mixed  $value
861
     * @param string $message
862
     *
863
     * @throws InvalidArgumentException
864
     */
865 51 View Code Duplication
    public static function ipv4($value, $message = '')
866
    {
867 51
        if (false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) {
868 35
            static::reportInvalidArgument(\sprintf(
869 35
                $message ?: 'Expected a value to be an IPv4. Got: %s',
870 35
                static::valueToString($value)
871
            ));
872
        }
873 16
    }
874
875
    /**
876
     * @param mixed  $value
877
     * @param string $message
878
     *
879
     * @throws InvalidArgumentException
880
     */
881 51 View Code Duplication
    public static function ipv6($value, $message = '')
882
    {
883 51
        if (false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
884 31
            static::reportInvalidArgument(\sprintf(
885 31
                $message ?: 'Expected a value to be an IPv6. Got: %s',
886 31
                static::valueToString($value)
887
            ));
888
        }
889 20
    }
890
891
    /**
892
     * @param mixed  $value
893
     * @param string $message
894
     *
895
     * @throws InvalidArgumentException
896
     */
897 20 View Code Duplication
    public static function email($value, $message = '')
898
    {
899 20
        if (false === \filter_var($value, FILTER_VALIDATE_EMAIL)) {
900 12
            static::reportInvalidArgument(\sprintf(
901 12
                $message ?: 'Expected a value to be a valid e-mail address. Got: %s',
902 12
                static::valueToString($value)
903
            ));
904
        }
905 8
    }
906
907
    /**
908
     * Does non strict comparisons on the items, so ['3', 3] will not pass the assertion.
909
     *
910
     * @param array  $values
911
     * @param string $message
912
     *
913
     * @throws InvalidArgumentException
914
     */
915 12
    public static function uniqueValues(array $values, $message = '')
916
    {
917 12
        $allValues = \count($values);
918 12
        $uniqueValues = \count(\array_unique($values));
919
920 12
        if ($allValues !== $uniqueValues) {
921 8
            $difference = $allValues - $uniqueValues;
922
923 8
            static::reportInvalidArgument(\sprintf(
924 8
                $message ?: 'Expected an array of unique values, but %s of them %s duplicated',
925 8
                $difference,
926 8
                (1 === $difference ? 'is' : 'are')
927
            ));
928
        }
929 4
    }
930
931
    /**
932
     * @param mixed  $value
933
     * @param mixed  $expect
934
     * @param string $message
935
     *
936
     * @throws InvalidArgumentException
937
     */
938 33
    public static function eq($value, $expect, $message = '')
939
    {
940 33
        if ($expect != $value) {
941 17
            static::reportInvalidArgument(\sprintf(
942 17
                $message ?: 'Expected a value equal to %2$s. Got: %s',
943 17
                static::valueToString($value),
944 17
                static::valueToString($expect)
945
            ));
946
        }
947 16
    }
948
949
    /**
950
     * @param mixed  $value
951
     * @param mixed  $expect
952
     * @param string $message
953
     *
954
     * @throws InvalidArgumentException
955
     */
956 28
    public static function notEq($value, $expect, $message = '')
957
    {
958 28
        if ($expect == $value) {
959 16
            static::reportInvalidArgument(\sprintf(
960 16
                $message ?: 'Expected a different value than %s.',
961 16
                static::valueToString($expect)
962
            ));
963
        }
964 12
    }
965
966
    /**
967
     * @psalm-pure
968
     *
969
     * @param mixed  $value
970
     * @param mixed  $expect
971
     * @param string $message
972
     *
973
     * @throws InvalidArgumentException
974
     */
975 16
    public static function same($value, $expect, $message = '')
976
    {
977 16
        if ($expect !== $value) {
978 12
            static::reportInvalidArgument(\sprintf(
979 12
                $message ?: 'Expected a value identical to %2$s. Got: %s',
980 12
                static::valueToString($value),
981 12
                static::valueToString($expect)
982
            ));
983
        }
984 4
    }
985
986
    /**
987
     * @psalm-pure
988
     *
989
     * @param mixed  $value
990
     * @param mixed  $expect
991
     * @param string $message
992
     *
993
     * @throws InvalidArgumentException
994
     */
995 16
    public static function notSame($value, $expect, $message = '')
996
    {
997 16
        if ($expect === $value) {
998 4
            static::reportInvalidArgument(\sprintf(
999 4
                $message ?: 'Expected a value not identical to %s.',
1000 4
                static::valueToString($expect)
1001
            ));
1002
        }
1003 12
    }
1004
1005
    /**
1006
     * @psalm-pure
1007
     *
1008
     * @param mixed  $value
1009
     * @param mixed  $limit
1010
     * @param string $message
1011
     *
1012
     * @throws InvalidArgumentException
1013
     */
1014 8
    public static function greaterThan($value, $limit, $message = '')
1015
    {
1016 8
        if ($value <= $limit) {
1017 4
            static::reportInvalidArgument(\sprintf(
1018 4
                $message ?: 'Expected a value greater than %2$s. Got: %s',
1019 4
                static::valueToString($value),
1020 4
                static::valueToString($limit)
1021
            ));
1022
        }
1023 4
    }
1024
1025
    /**
1026
     * @psalm-pure
1027
     *
1028
     * @param mixed  $value
1029
     * @param mixed  $limit
1030
     * @param string $message
1031
     *
1032
     * @throws InvalidArgumentException
1033
     */
1034 12
    public static function greaterThanEq($value, $limit, $message = '')
1035
    {
1036 12
        if ($value < $limit) {
1037 4
            static::reportInvalidArgument(\sprintf(
1038 4
                $message ?: 'Expected a value greater than or equal to %2$s. Got: %s',
1039 4
                static::valueToString($value),
1040 4
                static::valueToString($limit)
1041
            ));
1042
        }
1043 8
    }
1044
1045
    /**
1046
     * @psalm-pure
1047
     *
1048
     * @param mixed  $value
1049
     * @param mixed  $limit
1050
     * @param string $message
1051
     *
1052
     * @throws InvalidArgumentException
1053
     */
1054 9
    public static function lessThan($value, $limit, $message = '')
1055
    {
1056 9
        if ($value >= $limit) {
1057 5
            static::reportInvalidArgument(\sprintf(
1058 5
                $message ?: 'Expected a value less than %2$s. Got: %s',
1059 5
                static::valueToString($value),
1060 5
                static::valueToString($limit)
1061
            ));
1062
        }
1063 4
    }
1064
1065
    /**
1066
     * @psalm-pure
1067
     *
1068
     * @param mixed  $value
1069
     * @param mixed  $limit
1070
     * @param string $message
1071
     *
1072
     * @throws InvalidArgumentException
1073
     */
1074 12
    public static function lessThanEq($value, $limit, $message = '')
1075
    {
1076 12
        if ($value > $limit) {
1077 4
            static::reportInvalidArgument(\sprintf(
1078 4
                $message ?: 'Expected a value less than or equal to %2$s. Got: %s',
1079 4
                static::valueToString($value),
1080 4
                static::valueToString($limit)
1081
            ));
1082
        }
1083 8
    }
1084
1085
    /**
1086
     * Inclusive range, so Assert::(3, 3, 5) passes.
1087
     *
1088
     * @psalm-pure
1089
     *
1090
     * @param mixed  $value
1091
     * @param mixed  $min
1092
     * @param mixed  $max
1093
     * @param string $message
1094
     *
1095
     * @throws InvalidArgumentException
1096
     */
1097 16 View Code Duplication
    public static function range($value, $min, $max, $message = '')
1098
    {
1099 16
        if ($value < $min || $value > $max) {
1100 8
            static::reportInvalidArgument(\sprintf(
1101 8
                $message ?: 'Expected a value between %2$s and %3$s. Got: %s',
1102 8
                static::valueToString($value),
1103 8
                static::valueToString($min),
1104 8
                static::valueToString($max)
1105
            ));
1106
        }
1107 8
    }
1108
1109
    /**
1110
     * A more human-readable alias of Assert::inArray().
1111
     *
1112
     * @psalm-pure
1113
     *
1114
     * @param mixed  $value
1115
     * @param array  $values
1116
     * @param string $message
1117
     *
1118
     * @throws InvalidArgumentException
1119
     */
1120 8
    public static function oneOf($value, array $values, $message = '')
1121
    {
1122 8
        static::inArray($value, $values, $message);
1123 4
    }
1124
1125
    /**
1126
     * Does strict comparison, so Assert::inArray(3, ['3']) does not pass the assertion.
1127
     *
1128
     * @psalm-pure
1129
     *
1130
     * @param mixed  $value
1131
     * @param array  $values
1132
     * @param string $message
1133
     *
1134
     * @throws InvalidArgumentException
1135
     */
1136 16
    public static function inArray($value, array $values, $message = '')
1137
    {
1138 16
        if (!\in_array($value, $values, true)) {
1139 8
            static::reportInvalidArgument(\sprintf(
1140 8
                $message ?: 'Expected one of: %2$s. Got: %s',
1141 8
                static::valueToString($value),
1142 8
                \implode(', ', \array_map(array('static', 'valueToString'), $values))
1143
            ));
1144
        }
1145 8
    }
1146
1147
    /**
1148
     * @psalm-pure
1149
     *
1150
     * @param string $value
1151
     * @param string $subString
1152
     * @param string $message
1153
     *
1154
     * @throws InvalidArgumentException
1155
     */
1156 80 View Code Duplication
    public static function contains($value, $subString, $message = '')
1157
    {
1158 80
        if (false === \strpos($value, $subString)) {
1159 32
            static::reportInvalidArgument(\sprintf(
1160 32
                $message ?: 'Expected a value to contain %2$s. Got: %s',
1161 32
                static::valueToString($value),
1162 32
                static::valueToString($subString)
1163
            ));
1164
        }
1165 48
    }
1166
1167
    /**
1168
     * @psalm-pure
1169
     *
1170
     * @param string $value
1171
     * @param string $subString
1172
     * @param string $message
1173
     *
1174
     * @throws InvalidArgumentException
1175
     */
1176 80 View Code Duplication
    public static function notContains($value, $subString, $message = '')
1177
    {
1178 80
        if (false !== \strpos($value, $subString)) {
1179 48
            static::reportInvalidArgument(\sprintf(
1180 48
                $message ?: '%2$s was not expected to be contained in a value. Got: %s',
1181 48
                static::valueToString($value),
1182 48
                static::valueToString($subString)
1183
            ));
1184
        }
1185 32
    }
1186
1187
    /**
1188
     * @psalm-pure
1189
     *
1190
     * @param string $value
1191
     * @param string $message
1192
     *
1193
     * @throws InvalidArgumentException
1194
     */
1195 40
    public static function notWhitespaceOnly($value, $message = '')
1196
    {
1197 40
        if (\preg_match('/^\s*$/', $value)) {
1198 24
            static::reportInvalidArgument(\sprintf(
1199 24
                $message ?: 'Expected a non-whitespace string. Got: %s',
1200 24
                static::valueToString($value)
1201
            ));
1202
        }
1203 16
    }
1204
1205
    /**
1206
     * @psalm-pure
1207
     *
1208
     * @param string $value
1209
     * @param string $prefix
1210
     * @param string $message
1211
     *
1212
     * @throws InvalidArgumentException
1213
     */
1214 48 View Code Duplication
    public static function startsWith($value, $prefix, $message = '')
1215
    {
1216 48
        if (0 !== \strpos($value, $prefix)) {
1217 32
            static::reportInvalidArgument(\sprintf(
1218 32
                $message ?: 'Expected a value to start with %2$s. Got: %s',
1219 32
                static::valueToString($value),
1220 32
                static::valueToString($prefix)
1221
            ));
1222
        }
1223 16
    }
1224
1225
    /**
1226
     * @psalm-pure
1227
     *
1228
     * @param string $value
1229
     * @param string $prefix
1230
     * @param string $message
1231
     *
1232
     * @throws InvalidArgumentException
1233
     */
1234 48 View Code Duplication
    public static function notStartsWith($value, $prefix, $message = '')
1235
    {
1236 48
        if (0 === \strpos($value, $prefix)) {
1237 16
            static::reportInvalidArgument(\sprintf(
1238 16
                $message ?: 'Expected a value not to start with %2$s. Got: %s',
1239 16
                static::valueToString($value),
1240 16
                static::valueToString($prefix)
1241
            ));
1242
        }
1243 32
    }
1244
1245
    /**
1246
     * @psalm-pure
1247
     *
1248
     * @param mixed  $value
1249
     * @param string $message
1250
     *
1251
     * @throws InvalidArgumentException
1252
     */
1253 35
    public static function startsWithLetter($value, $message = '')
1254
    {
1255 35
        static::string($value);
1256
1257 24
        $valid = isset($value[0]);
1258
1259 24
        if ($valid) {
1260 20
            $locale = \setlocale(LC_CTYPE, 0);
1261 20
            \setlocale(LC_CTYPE, 'C');
1262 20
            $valid = \ctype_alpha($value[0]);
1263 20
            \setlocale(LC_CTYPE, $locale);
1264
        }
1265
1266 24
        if (!$valid) {
1267 12
            static::reportInvalidArgument(\sprintf(
1268 12
                $message ?: 'Expected a value to start with a letter. Got: %s',
1269 12
                static::valueToString($value)
1270
            ));
1271
        }
1272 12
    }
1273
1274
    /**
1275
     * @psalm-pure
1276
     *
1277
     * @param string $value
1278
     * @param string $suffix
1279
     * @param string $message
1280
     *
1281
     * @throws InvalidArgumentException
1282
     */
1283 48 View Code Duplication
    public static function endsWith($value, $suffix, $message = '')
1284
    {
1285 48
        if ($suffix !== \substr($value, -\strlen($suffix))) {
1286 32
            static::reportInvalidArgument(\sprintf(
1287 32
                $message ?: 'Expected a value to end with %2$s. Got: %s',
1288 32
                static::valueToString($value),
1289 32
                static::valueToString($suffix)
1290
            ));
1291
        }
1292 16
    }
1293
1294
    /**
1295
     * @psalm-pure
1296
     *
1297
     * @param string $value
1298
     * @param string $suffix
1299
     * @param string $message
1300
     *
1301
     * @throws InvalidArgumentException
1302
     */
1303 48 View Code Duplication
    public static function notEndsWith($value, $suffix, $message = '')
1304
    {
1305 48
        if ($suffix === \substr($value, -\strlen($suffix))) {
1306 16
            static::reportInvalidArgument(\sprintf(
1307 16
                $message ?: 'Expected a value not to end with %2$s. Got: %s',
1308 16
                static::valueToString($value),
1309 16
                static::valueToString($suffix)
1310
            ));
1311
        }
1312 32
    }
1313
1314
    /**
1315
     * @psalm-pure
1316
     *
1317
     * @param string $value
1318
     * @param string $pattern
1319
     * @param string $message
1320
     *
1321
     * @throws InvalidArgumentException
1322
     */
1323 12
    public static function regex($value, $pattern, $message = '')
1324
    {
1325 12
        if (!\preg_match($pattern, $value)) {
1326 8
            static::reportInvalidArgument(\sprintf(
1327 8
                $message ?: 'The value %s does not match the expected pattern.',
1328 8
                static::valueToString($value)
1329
            ));
1330
        }
1331 4
    }
1332
1333
    /**
1334
     * @psalm-pure
1335
     *
1336
     * @param string $value
1337
     * @param string $pattern
1338
     * @param string $message
1339
     *
1340
     * @throws InvalidArgumentException
1341
     */
1342 12
    public static function notRegex($value, $pattern, $message = '')
1343
    {
1344 12
        if (\preg_match($pattern, $value, $matches, PREG_OFFSET_CAPTURE)) {
1345 4
            static::reportInvalidArgument(\sprintf(
1346 4
                $message ?: 'The value %s matches the pattern %s (at offset %d).',
1347 4
                static::valueToString($value),
1348 4
                static::valueToString($pattern),
1349 4
                $matches[0][1]
1350
            ));
1351
        }
1352 8
    }
1353
1354
    /**
1355
     * @psalm-pure
1356
     *
1357
     * @param mixed  $value
1358
     * @param string $message
1359
     *
1360
     * @throws InvalidArgumentException
1361
     */
1362 28 View Code Duplication
    public static function unicodeLetters($value, $message = '')
1363
    {
1364 28
        static::string($value);
1365
1366 28
        if (!\preg_match('/^\p{L}+$/u', $value)) {
1367 16
            static::reportInvalidArgument(\sprintf(
1368 16
                $message ?: 'Expected a value to contain only Unicode letters. Got: %s',
1369 16
                static::valueToString($value)
1370
            ));
1371
        }
1372 12
    }
1373
1374
    /**
1375
     * @psalm-pure
1376
     *
1377
     * @param mixed  $value
1378
     * @param string $message
1379
     *
1380
     * @throws InvalidArgumentException
1381
     */
1382 20 View Code Duplication
    public static function alpha($value, $message = '')
1383
    {
1384 20
        static::string($value);
1385
1386 12
        $locale = \setlocale(LC_CTYPE, 0);
1387 12
        \setlocale(LC_CTYPE, 'C');
1388 12
        $valid = !\ctype_alpha($value);
1389 12
        \setlocale(LC_CTYPE, $locale);
1390
1391 12
        if ($valid) {
1392 8
            static::reportInvalidArgument(\sprintf(
1393 8
                $message ?: 'Expected a value to contain only letters. Got: %s',
1394 8
                static::valueToString($value)
1395
            ));
1396
        }
1397 4
    }
1398
1399
    /**
1400
     * @psalm-pure
1401
     *
1402
     * @param string $value
1403
     * @param string $message
1404
     *
1405
     * @throws InvalidArgumentException
1406
     */
1407 12 View Code Duplication
    public static function digits($value, $message = '')
1408
    {
1409 12
        $locale = \setlocale(LC_CTYPE, 0);
1410 12
        \setlocale(LC_CTYPE, 'C');
1411 12
        $valid = !\ctype_digit($value);
1412 12
        \setlocale(LC_CTYPE, $locale);
1413
1414 12
        if ($valid) {
1415 8
            static::reportInvalidArgument(\sprintf(
1416 8
                $message ?: 'Expected a value to contain digits only. Got: %s',
1417 8
                static::valueToString($value)
1418
            ));
1419
        }
1420 4
    }
1421
1422
    /**
1423
     * @psalm-pure
1424
     *
1425
     * @param string $value
1426
     * @param string $message
1427
     *
1428
     * @throws InvalidArgumentException
1429
     */
1430 12 View Code Duplication
    public static function alnum($value, $message = '')
1431
    {
1432 12
        $locale = \setlocale(LC_CTYPE, 0);
1433 12
        \setlocale(LC_CTYPE, 'C');
1434 12
        $valid = !\ctype_alnum($value);
1435 12
        \setlocale(LC_CTYPE, $locale);
1436
1437 12
        if ($valid) {
1438 8
            static::reportInvalidArgument(\sprintf(
1439 8
                $message ?: 'Expected a value to contain letters and digits only. Got: %s',
1440 8
                static::valueToString($value)
1441
            ));
1442
        }
1443 4
    }
1444
1445
    /**
1446
     * @psalm-pure
1447
     * @psalm-assert lowercase-string $value
1448
     *
1449
     * @param string $value
1450
     * @param string $message
1451
     *
1452
     * @throws InvalidArgumentException
1453
     */
1454 16 View Code Duplication
    public static function lower($value, $message = '')
1455
    {
1456 16
        $locale = \setlocale(LC_CTYPE, 0);
1457 16
        \setlocale(LC_CTYPE, 'C');
1458 16
        $valid = !\ctype_lower($value);
1459 16
        \setlocale(LC_CTYPE, $locale);
1460
1461 16
        if ($valid) {
1462 12
            static::reportInvalidArgument(\sprintf(
1463 12
                $message ?: 'Expected a value to contain lowercase characters only. Got: %s',
1464 12
                static::valueToString($value)
1465
            ));
1466
        }
1467 4
    }
1468
1469
    /**
1470
     * @psalm-pure
1471
     * @psalm-assert !lowercase-string $value
1472
     *
1473
     * @param string $value
1474
     * @param string $message
1475
     *
1476
     * @throws InvalidArgumentException
1477
     */
1478 16 View Code Duplication
    public static function upper($value, $message = '')
1479
    {
1480 16
        $locale = \setlocale(LC_CTYPE, 0);
1481 16
        \setlocale(LC_CTYPE, 'C');
1482 16
        $valid = !\ctype_upper($value);
1483 16
        \setlocale(LC_CTYPE, $locale);
1484
1485 16
        if ($valid) {
1486 12
            static::reportInvalidArgument(\sprintf(
1487 12
                $message ?: 'Expected a value to contain uppercase characters only. Got: %s',
1488 12
                static::valueToString($value)
1489
            ));
1490
        }
1491 4
    }
1492
1493
    /**
1494
     * @psalm-pure
1495
     *
1496
     * @param string $value
1497
     * @param int    $length
1498
     * @param string $message
1499
     *
1500
     * @throws InvalidArgumentException
1501
     */
1502 36
    public static function length($value, $length, $message = '')
1503
    {
1504 36
        if ($length !== static::strlen($value)) {
1505 24
            static::reportInvalidArgument(\sprintf(
1506 24
                $message ?: 'Expected a value to contain %2$s characters. Got: %s',
1507 24
                static::valueToString($value),
1508 24
                $length
1509
            ));
1510
        }
1511 12
    }
1512
1513
    /**
1514
     * Inclusive min.
1515
     *
1516
     * @psalm-pure
1517
     *
1518
     * @param string    $value
1519
     * @param int|float $min
1520
     * @param string    $message
1521
     *
1522
     * @throws InvalidArgumentException
1523
     */
1524 36
    public static function minLength($value, $min, $message = '')
1525
    {
1526 36
        if (static::strlen($value) < $min) {
1527 12
            static::reportInvalidArgument(\sprintf(
1528 12
                $message ?: 'Expected a value to contain at least %2$s characters. Got: %s',
1529 12
                static::valueToString($value),
1530 12
                $min
1531
            ));
1532
        }
1533 24
    }
1534
1535
    /**
1536
     * Inclusive max.
1537
     *
1538
     * @psalm-pure
1539
     *
1540
     * @param string    $value
1541
     * @param int|float $max
1542
     * @param string    $message
1543
     *
1544
     * @throws InvalidArgumentException
1545
     */
1546 36
    public static function maxLength($value, $max, $message = '')
1547
    {
1548 36
        if (static::strlen($value) > $max) {
1549 12
            static::reportInvalidArgument(\sprintf(
1550 12
                $message ?: 'Expected a value to contain at most %2$s characters. Got: %s',
1551 12
                static::valueToString($value),
1552 12
                $max
1553
            ));
1554
        }
1555 24
    }
1556
1557
    /**
1558
     * Inclusive , so Assert::lengthBetween('asd', 3, 5); passes the assertion.
1559
     *
1560
     * @psalm-pure
1561
     *
1562
     * @param string    $value
1563
     * @param int|float $min
1564
     * @param int|float $max
1565
     * @param string    $message
1566
     *
1567
     * @throws InvalidArgumentException
1568
     */
1569 60 View Code Duplication
    public static function lengthBetween($value, $min, $max, $message = '')
1570
    {
1571 60
        $length = static::strlen($value);
1572
1573 60
        if ($length < $min || $length > $max) {
1574 24
            static::reportInvalidArgument(\sprintf(
1575 24
                $message ?: 'Expected a value to contain between %2$s and %3$s characters. Got: %s',
1576 24
                static::valueToString($value),
1577 24
                $min,
1578 24
                $max
1579
            ));
1580
        }
1581 36
    }
1582
1583
    /**
1584
     * Will also pass if $value is a directory, use Assert::file() instead if you need to be sure it is a file.
1585
     *
1586
     * @param mixed  $value
1587
     * @param string $message
1588
     *
1589
     * @throws InvalidArgumentException
1590
     */
1591 36 View Code Duplication
    public static function fileExists($value, $message = '')
1592
    {
1593 36
        static::string($value);
1594
1595 36
        if (!\file_exists($value)) {
1596 12
            static::reportInvalidArgument(\sprintf(
1597 12
                $message ?: 'The file %s does not exist.',
1598 12
                static::valueToString($value)
1599
            ));
1600
        }
1601 24
    }
1602
1603
    /**
1604
     * @param mixed  $value
1605
     * @param string $message
1606
     *
1607
     * @throws InvalidArgumentException
1608
     */
1609 12 View Code Duplication
    public static function file($value, $message = '')
1610
    {
1611 12
        static::fileExists($value, $message);
1612
1613 8
        if (!\is_file($value)) {
1614 4
            static::reportInvalidArgument(\sprintf(
1615 4
                $message ?: 'The path %s is not a file.',
1616 4
                static::valueToString($value)
1617
            ));
1618
        }
1619 4
    }
1620
1621
    /**
1622
     * @param mixed  $value
1623
     * @param string $message
1624
     *
1625
     * @throws InvalidArgumentException
1626
     */
1627 12 View Code Duplication
    public static function directory($value, $message = '')
1628
    {
1629 12
        static::fileExists($value, $message);
1630
1631 8
        if (!\is_dir($value)) {
1632 4
            static::reportInvalidArgument(\sprintf(
1633 4
                $message ?: 'The path %s is no directory.',
1634 4
                static::valueToString($value)
1635
            ));
1636
        }
1637 4
    }
1638
1639
    /**
1640
     * @param string $value
1641
     * @param string $message
1642
     *
1643
     * @throws InvalidArgumentException
1644
     */
1645
    public static function readable($value, $message = '')
1646
    {
1647
        if (!\is_readable($value)) {
1648
            static::reportInvalidArgument(\sprintf(
1649
                $message ?: 'The path %s is not readable.',
1650
                static::valueToString($value)
1651
            ));
1652
        }
1653
    }
1654
1655
    /**
1656
     * @param string $value
1657
     * @param string $message
1658
     *
1659
     * @throws InvalidArgumentException
1660
     */
1661
    public static function writable($value, $message = '')
1662
    {
1663
        if (!\is_writable($value)) {
1664
            static::reportInvalidArgument(\sprintf(
1665
                $message ?: 'The path %s is not writable.',
1666
                static::valueToString($value)
1667
            ));
1668
        }
1669
    }
1670
1671
    /**
1672
     * @psalm-assert class-string $value
1673
     *
1674
     * @param mixed  $value
1675
     * @param string $message
1676
     *
1677
     * @throws InvalidArgumentException
1678
     */
1679 8
    public static function classExists($value, $message = '')
1680
    {
1681 8
        if (!\class_exists($value)) {
1682 4
            static::reportInvalidArgument(\sprintf(
1683 4
                $message ?: 'Expected an existing class name. Got: %s',
1684 4
                static::valueToString($value)
1685
            ));
1686
        }
1687 4
    }
1688
1689
    /**
1690
     * @psalm-pure
1691
     * @psalm-template ExpectedType of object
1692
     * @psalm-param class-string<ExpectedType> $class
1693
     * @psalm-assert class-string<ExpectedType>|ExpectedType $value
1694
     *
1695
     * @param mixed         $value
1696
     * @param string|object $class
1697
     * @param string        $message
1698
     *
1699
     * @throws InvalidArgumentException
1700
     */
1701 8
    public static function subclassOf($value, $class, $message = '')
1702
    {
1703 8
        if (!\is_subclass_of($value, $class)) {
1704 4
            static::reportInvalidArgument(\sprintf(
1705 4
                $message ?: 'Expected a sub-class of %2$s. Got: %s',
1706 4
                static::valueToString($value),
1707 4
                static::valueToString($class)
1708
            ));
1709
        }
1710 4
    }
1711
1712
    /**
1713
     * @param mixed  $value
1714
     * @param string $message
1715
     *
1716
     * @throws InvalidArgumentException
1717
     */
1718 8
    public static function interfaceExists($value, $message = '')
1719
    {
1720 8
        if (!\interface_exists($value)) {
1721 4
            static::reportInvalidArgument(\sprintf(
1722 4
                $message ?: 'Expected an existing interface name. got %s',
1723 4
                static::valueToString($value)
1724
            ));
1725
        }
1726 4
    }
1727
1728
    /**
1729
     * @psalm-pure
1730
     * @psalm-template ExpectedType of object
1731
     * @psalm-param class-string<ExpectedType> $interface
1732
     * @psalm-assert class-string<ExpectedType> $value
1733
     *
1734
     * @param mixed  $value
1735
     * @param mixed  $interface
1736
     * @param string $message
1737
     *
1738
     * @throws InvalidArgumentException
1739
     */
1740 8 View Code Duplication
    public static function implementsInterface($value, $interface, $message = '')
1741
    {
1742 8
        if (!\in_array($interface, \class_implements($value))) {
1743 4
            static::reportInvalidArgument(\sprintf(
1744 4
                $message ?: 'Expected an implementation of %2$s. Got: %s',
1745 4
                static::valueToString($value),
1746 4
                static::valueToString($interface)
1747
            ));
1748
        }
1749 4
    }
1750
1751
    /**
1752
     * @psalm-pure
1753
     * @psalm-param class-string|object $classOrObject
1754
     *
1755
     * @param string|object $classOrObject
1756
     * @param mixed         $property
1757
     * @param string        $message
1758
     *
1759
     * @throws InvalidArgumentException
1760
     */
1761 12 View Code Duplication
    public static function propertyExists($classOrObject, $property, $message = '')
1762
    {
1763 12
        if (!\property_exists($classOrObject, $property)) {
1764 4
            static::reportInvalidArgument(\sprintf(
1765 4
                $message ?: 'Expected the property %s to exist.',
1766 4
                static::valueToString($property)
1767
            ));
1768
        }
1769 8
    }
1770
1771
    /**
1772
     * @psalm-pure
1773
     * @psalm-param class-string|object $classOrObject
1774
     *
1775
     * @param string|object $classOrObject
1776
     * @param mixed         $property
1777
     * @param string        $message
1778
     *
1779
     * @throws InvalidArgumentException
1780
     */
1781 12 View Code Duplication
    public static function propertyNotExists($classOrObject, $property, $message = '')
1782
    {
1783 12
        if (\property_exists($classOrObject, $property)) {
1784 8
            static::reportInvalidArgument(\sprintf(
1785 8
                $message ?: 'Expected the property %s to not exist.',
1786 8
                static::valueToString($property)
1787
            ));
1788
        }
1789 4
    }
1790
1791
    /**
1792
     * @psalm-pure
1793
     * @psalm-param class-string|object $classOrObject
1794
     *
1795
     * @param string|object $classOrObject
1796
     * @param mixed         $method
1797
     * @param string        $message
1798
     *
1799
     * @throws InvalidArgumentException
1800
     */
1801 27 View Code Duplication
    public static function methodExists($classOrObject, $method, $message = '')
1802
    {
1803 27
        if (!\method_exists($classOrObject, $method)) {
1804 19
            static::reportInvalidArgument(\sprintf(
1805 19
                $message ?: 'Expected the method %s to exist.',
1806 19
                static::valueToString($method)
1807
            ));
1808
        }
1809 8
    }
1810
1811
    /**
1812
     * @psalm-pure
1813
     * @psalm-param class-string|object $classOrObject
1814
     *
1815
     * @param string|object $classOrObject
1816
     * @param mixed         $method
1817
     * @param string        $message
1818
     *
1819
     * @throws InvalidArgumentException
1820
     */
1821 27 View Code Duplication
    public static function methodNotExists($classOrObject, $method, $message = '')
1822
    {
1823 27
        if (\method_exists($classOrObject, $method)) {
1824 8
            static::reportInvalidArgument(\sprintf(
1825 8
                $message ?: 'Expected the method %s to not exist.',
1826 8
                static::valueToString($method)
1827
            ));
1828
        }
1829 19
    }
1830
1831
    /**
1832
     * @psalm-pure
1833
     *
1834
     * @param array      $array
1835
     * @param string|int $key
1836
     * @param string     $message
1837
     *
1838
     * @throws InvalidArgumentException
1839
     */
1840 12 View Code Duplication
    public static function keyExists($array, $key, $message = '')
1841
    {
1842 12
        if (!(isset($array[$key]) || \array_key_exists($key, $array))) {
1843 4
            static::reportInvalidArgument(\sprintf(
1844 4
                $message ?: 'Expected the key %s to exist.',
1845 4
                static::valueToString($key)
1846
            ));
1847
        }
1848 8
    }
1849
1850
    /**
1851
     * @psalm-pure
1852
     *
1853
     * @param array      $array
1854
     * @param string|int $key
1855
     * @param string     $message
1856
     *
1857
     * @throws InvalidArgumentException
1858
     */
1859 12 View Code Duplication
    public static function keyNotExists($array, $key, $message = '')
1860
    {
1861 12
        if (isset($array[$key]) || \array_key_exists($key, $array)) {
1862 8
            static::reportInvalidArgument(\sprintf(
1863 8
                $message ?: 'Expected the key %s to not exist.',
1864 8
                static::valueToString($key)
1865
            ));
1866
        }
1867 4
    }
1868
1869
    /**
1870
     * Checks if a value is a valid array key (int or string).
1871
     *
1872
     * @psalm-pure
1873
     * @psalm-assert array-key $value
1874
     *
1875
     * @param mixed  $value
1876
     * @param string $message
1877
     *
1878
     * @throws InvalidArgumentException
1879
     */
1880 28
    public static function validArrayKey($value, $message = '')
1881
    {
1882 28
        if (!(\is_int($value) || \is_string($value))) {
1883 20
            static::reportInvalidArgument(\sprintf(
1884 20
                $message ?: 'Expected string or integer. Got: %s',
1885 20
                static::typeToString($value)
1886
            ));
1887
        }
1888 8
    }
1889
1890
    /**
1891
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1892
     *
1893
     * @param Countable|array $array
1894
     * @param int             $number
1895
     * @param string          $message
1896
     *
1897
     * @throws InvalidArgumentException
1898
     */
1899 8
    public static function count($array, $number, $message = '')
1900
    {
1901 8
        static::eq(
1902 8
            \count($array),
1903
            $number,
1904 8
            \sprintf(
1905 8
                $message ?: 'Expected an array to contain %d elements. Got: %d.',
1906 8
                $number,
1907 8
                \count($array)
1908
            )
1909
        );
1910 4
    }
1911
1912
    /**
1913
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1914
     *
1915
     * @param Countable|array $array
1916
     * @param int|float       $min
1917
     * @param string          $message
1918
     *
1919
     * @throws InvalidArgumentException
1920
     */
1921 12 View Code Duplication
    public static function minCount($array, $min, $message = '')
1922
    {
1923 12
        if (\count($array) < $min) {
1924 4
            static::reportInvalidArgument(\sprintf(
1925 4
                $message ?: 'Expected an array to contain at least %2$d elements. Got: %d',
1926 4
                \count($array),
1927 4
                $min
1928
            ));
1929
        }
1930 8
    }
1931
1932
    /**
1933
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1934
     *
1935
     * @param Countable|array $array
1936
     * @param int|float       $max
1937
     * @param string          $message
1938
     *
1939
     * @throws InvalidArgumentException
1940
     */
1941 12 View Code Duplication
    public static function maxCount($array, $max, $message = '')
1942
    {
1943 12
        if (\count($array) > $max) {
1944 4
            static::reportInvalidArgument(\sprintf(
1945 4
                $message ?: 'Expected an array to contain at most %2$d elements. Got: %d',
1946 4
                \count($array),
1947 4
                $max
1948
            ));
1949
        }
1950 8
    }
1951
1952
    /**
1953
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1954
     *
1955
     * @param Countable|array $array
1956
     * @param int|float       $min
1957
     * @param int|float       $max
1958
     * @param string          $message
1959
     *
1960
     * @throws InvalidArgumentException
1961
     */
1962 20
    public static function countBetween($array, $min, $max, $message = '')
1963
    {
1964 20
        $count = \count($array);
1965
1966 20
        if ($count < $min || $count > $max) {
1967 8
            static::reportInvalidArgument(\sprintf(
1968 8
                $message ?: 'Expected an array to contain between %2$d and %3$d elements. Got: %d',
1969 8
                $count,
1970 8
                $min,
1971 8
                $max
1972
            ));
1973
        }
1974 12
    }
1975
1976
    /**
1977
     * @psalm-pure
1978
     * @psalm-assert list $array
1979
     *
1980
     * @param mixed  $array
1981
     * @param string $message
1982
     *
1983
     * @throws InvalidArgumentException
1984
     */
1985 80 View Code Duplication
    public static function isList($array, $message = '')
1986
    {
1987 80
        if (!\is_array($array) || $array !== \array_values($array)) {
1988 32
            static::reportInvalidArgument(
1989 32
                $message ?: 'Expected list - non-associative array.'
1990
            );
1991
        }
1992 48
    }
1993
1994
    /**
1995
     * @psalm-pure
1996
     * @psalm-assert list $array
1997
     * @psalm-assert !empty $array
1998
     *
1999
     * @param mixed  $array
2000
     * @param string $message
2001
     *
2002
     * @throws InvalidArgumentException
2003
     */
2004 40
    public static function isNonEmptyList($array, $message = '')
2005
    {
2006 40
        static::isList($array, $message);
2007 24
        static::notEmpty($array, $message);
2008 20
    }
2009
2010
    /**
2011
     * @psalm-pure
2012
     * @psalm-template T
2013
     * @psalm-param mixed|array<T> $array
2014
     * @psalm-assert array<string, T> $array
2015
     *
2016
     * @param mixed  $array
2017
     * @param string $message
2018
     *
2019
     * @throws InvalidArgumentException
2020
     */
2021 32
    public static function isMap($array, $message = '')
2022
    {
2023
        if (
2024 32
            !\is_array($array) ||
2025 32
            \array_keys($array) !== \array_filter(\array_keys($array), '\is_string')
2026
        ) {
2027 16
            static::reportInvalidArgument(
2028 16
                $message ?: 'Expected map - associative array with string keys.'
2029
            );
2030
        }
2031 16
    }
2032
2033
    /**
2034
     * @psalm-pure
2035
     * @psalm-template T
2036
     * @psalm-param mixed|array<T> $array
2037
     * @psalm-assert array<string, T> $array
2038
     * @psalm-assert !empty $array
2039
     *
2040
     * @param mixed  $array
2041
     * @param string $message
2042
     *
2043
     * @throws InvalidArgumentException
2044
     */
2045 16
    public static function isNonEmptyMap($array, $message = '')
2046
    {
2047 16
        static::isMap($array, $message);
2048 8
        static::notEmpty($array, $message);
2049 4
    }
2050
2051
    /**
2052
     * @psalm-pure
2053
     *
2054
     * @param string $value
2055
     * @param string $message
2056
     *
2057
     * @throws InvalidArgumentException
2058
     */
2059 56
    public static function uuid($value, $message = '')
2060
    {
2061 56
        $value = \str_replace(array('urn:', 'uuid:', '{', '}'), '', $value);
2062
2063
        // The nil UUID is special form of UUID that is specified to have all
2064
        // 128 bits set to zero.
2065 56
        if ('00000000-0000-0000-0000-000000000000' === $value) {
2066 4
            return;
2067
        }
2068
2069 52
        if (!\preg_match('/^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/', $value)) {
2070 20
            static::reportInvalidArgument(\sprintf(
2071 20
                $message ?: 'Value %s is not a valid UUID.',
2072 20
                static::valueToString($value)
2073
            ));
2074
        }
2075 32
    }
2076
2077
    /**
2078
     * @psalm-param class-string<Throwable>
2079
     *
2080
     * @param Closure $expression
2081
     * @param string  $class
2082
     * @param string  $message
2083
     *
2084
     * @throws InvalidArgumentException
2085
     */
2086 24
    public static function throws(Closure $expression, $class = 'Exception', $message = '')
2087
    {
2088 24
        static::string($class);
2089
2090 24
        $actual = 'none';
2091
2092
        try {
2093 24
            $expression();
2094 24
        } catch (Exception $e) {
2095 20
            $actual = \get_class($e);
2096 20
            if ($e instanceof $class) {
2097 20
                return;
2098
            }
2099 4
        } catch (Throwable $e) {
2100 4
            $actual = \get_class($e);
2101 4
            if ($e instanceof $class) {
2102 4
                return;
2103
            }
2104
        }
2105
2106 8
        static::reportInvalidArgument($message ?: \sprintf(
2107 8
            'Expected to throw "%s", got "%s"',
2108 8
            $class,
2109 8
            $actual
2110
        ));
2111
    }
2112
2113
    /**
2114
     * @throws BadMethodCallException
2115
     */
2116 1642
    public static function __callStatic($name, $arguments)
2117
    {
2118 1642
        if ('nullOr' === \substr($name, 0, 6)) {
2119 607
            if (null !== $arguments[0]) {
2120 501
                $method = \lcfirst(\substr($name, 6));
2121 501
                \call_user_func_array(array('static', $method), $arguments);
2122
            }
2123
2124 354
            return;
2125
        }
2126
2127 1035
        if ('all' === \substr($name, 0, 3)) {
2128 1034
            static::isIterable($arguments[0]);
2129
2130 1034
            $method = \lcfirst(\substr($name, 3));
2131 1034
            $args = $arguments;
2132
2133 1034
            foreach ($arguments[0] as $entry) {
2134 1034
                $args[0] = $entry;
2135
2136 1034
                \call_user_func_array(array('static', $method), $args);
2137
            }
2138
2139 504
            return;
2140
        }
2141
2142 1
        throw new BadMethodCallException('No such method: '.$name);
2143
    }
2144
2145
    /**
2146
     * @param mixed $value
2147
     *
2148
     * @return string
2149
     */
2150 751
    protected static function valueToString($value)
2151
    {
2152 751
        if (null === $value) {
2153 20
            return 'null';
2154
        }
2155
2156 733
        if (true === $value) {
2157 15
            return 'true';
2158
        }
2159
2160 723
        if (false === $value) {
2161 25
            return 'false';
2162
        }
2163
2164 698
        if (\is_array($value)) {
2165 21
            return 'array';
2166
        }
2167
2168 677
        if (\is_object($value)) {
2169 3
            if (\method_exists($value, '__toString')) {
2170 1
                return \get_class($value).': '.self::valueToString($value->__toString());
2171
            }
2172
2173 2
            if ($value instanceof DateTime || $value instanceof DateTimeImmutable) {
2174 1
                return \get_class($value).': '.self::valueToString($value->format('c'));
2175
            }
2176
2177 1
            return \get_class($value);
2178
        }
2179
2180 676
        if (\is_resource($value)) {
2181 1
            return 'resource';
2182
        }
2183
2184 676
        if (\is_string($value)) {
2185 574
            return '"'.$value.'"';
2186
        }
2187
2188 114
        return (string) $value;
2189
    }
2190
2191
    /**
2192
     * @param mixed $value
2193
     *
2194
     * @return string
2195
     */
2196 251
    protected static function typeToString($value)
2197
    {
2198 251
        return \is_object($value) ? \get_class($value) : \gettype($value);
2199
    }
2200
2201 168
    protected static function strlen($value)
2202
    {
2203 168
        if (!\function_exists('mb_detect_encoding')) {
2204
            return \strlen($value);
2205
        }
2206
2207 168
        if (false === $encoding = \mb_detect_encoding($value)) {
2208
            return \strlen($value);
2209
        }
2210
2211 168
        return \mb_strlen($value, $encoding);
2212
    }
2213
2214
    /**
2215
     * @param string $message
2216
     *
2217
     * @throws InvalidArgumentException
2218
     *
2219
     * @psalm-pure this method is not supposed to perform side-effects
2220
     */
2221 1065
    protected static function reportInvalidArgument($message)
2222
    {
2223 1065
        throw new InvalidArgumentException($message);
2224
    }
2225
2226
    private function __construct()
2227
    {
2228
    }
2229
}
2230