Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
24 / 24
96.43% covered (success)
96.43%
27 / 28
46.43% covered (danger)
46.43%
13 / 28
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Boolean
100.00% covered (success)
100.00%
24 / 24
96.43% covered (success)
96.43%
27 / 28
46.43% covered (danger)
46.43%
13 / 28
100.00% covered (success)
100.00%
4 / 4
49.59
100.00% covered (success)
100.00%
1 / 1
 coerce
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
5
 invalid
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 toBoolean
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
5
 toStringBoolean
100.00% covered (success)
100.00%
5 / 5
87.50% covered (warning)
87.50%
7 / 8
16.67% covered (danger)
16.67%
3 / 18
100.00% covered (success)
100.00%
1 / 1
13.26
1<?php
2
3declare(strict_types=1);
4
5namespace Celemas\Sire\Coercer;
6
7use Celemas\Sire\Coercion;
8use Celemas\Sire\CoercionMode;
9use Celemas\Sire\Contract;
10use Celemas\Sire\Failure;
11use Override;
12
13/** @api */
14final class Boolean implements Contract\Coercer
15{
16    public string $message {
17        get => '{label} must be true or false';
18    }
19
20    #[Override]
21    public function coerce(mixed $pristine, CoercionMode $mode): Contract\Coercion
22    {
23        if ($pristine === null) {
24            return new Coercion(null, null, empty: true);
25        }
26
27        if (is_bool($pristine)) {
28            return new Coercion($pristine, $pristine);
29        }
30
31        if ($mode === CoercionMode::Strict) {
32            return self::invalid($pristine);
33        }
34
35        $value = self::toBoolean($pristine);
36
37        return $value === null
38            ? self::invalid($pristine)
39            : new Coercion($value, $pristine);
40    }
41
42    private static function invalid(mixed $pristine): Coercion
43    {
44        return new Coercion(
45            $pristine,
46            $pristine,
47            Failure::invalid(),
48        );
49    }
50
51    private static function toBoolean(mixed $value): ?bool
52    {
53        return match (true) {
54            $value === 1 => true,
55            $value === 0 => false,
56            is_string($value) => self::toStringBoolean($value),
57            default => null,
58        };
59    }
60
61    private static function toStringBoolean(string $value): ?bool
62    {
63        return match (strtolower(trim($value))) {
64            '1', 'true', 'on', 'yes' => true,
65            '0', 'false', 'off', 'no' => false,
66            default => null,
67        };
68    }
69}