Passed
Push — develop ( 7d2249...4ccadf )
by Baptiste
02:09
created

Arguments::all()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Compose;
5
6
use Innmind\Compose\{
7
    Definition\Argument,
8
    Definition\Name,
9
    Exception\MissingArgument,
10
    Exception\ArgumentNotProvided,
11
    Exception\ArgumentNotDefined
12
};
13
use Innmind\Immutable\{
14
    Sequence,
15
    MapInterface,
16
    Map,
17
    SetInterface,
18
    Set
19
};
20
21
final class Arguments
22
{
23
    private $arguments;
24
    private $values;
25
26 207
    public function __construct(Argument ...$arguments)
27
    {
28 207
        $this->arguments = Sequence::of(...$arguments)->reduce(
29 207
            new Map('string', Argument::class),
30 207
            static function(Map $arguments, Argument $argument): Map {
31 56
                return $arguments->put(
32 56
                    (string) $argument->name(),
33 56
                    $argument
34
                );
35 207
            }
36
        );
37 207
        $this->values = new Map('string', 'mixed');
38 207
    }
39
40
    /**
41
     * @param MapInterface<string, mixed> $values
42
     *
43
     * @throws MissingArgument
44
     */
45 42
    public function bind(MapInterface $values): self
46
    {
47
        if (
48 42
            (string) $values->keyType() !== 'string' ||
49 42
            (string) $values->valueType() !== 'mixed'
50
        ) {
51 1
            throw new \TypeError('Argument 1 must be of type MapInterface<string, mixed>');
52
        }
53
54
        $this
55 41
            ->arguments
56 41
            ->filter(static function(string $name, Argument $argument): bool {
57 40
                return !$argument->optional() && !$argument->hasDefault();
58 41
            })
59 41
            ->foreach(static function(string $name) use ($values): void {
60 34
                if (!$values->contains($name)) {
61 1
                    throw new MissingArgument($name);
62
                }
63 41
            });
64
        $this
65 40
            ->arguments
66 40
            ->filter(static function(string $name) use ($values): bool {
67 39
                return $values->contains($name);
68 40
            })
69 40
            ->foreach(static function(string $name, Argument $argument) use ($values): void {
70 33
                $argument->validate($values->get($name));
71 40
            });
72
73 39
        $self = clone $this;
74 39
        $self->values = $values;
75
76 39
        return $self;
77
    }
78
79
    /**
80
     * @throws ArgumentNotProvided
81
     *
82
     * @return mixed
83
     */
84 37
    public function get(Name $name)
85
    {
86 37
        if (!$this->arguments->contains((string) $name)) {
87 21
            throw new ArgumentNotDefined((string) $name);
88
        }
89
90 26
        if (!$this->values->contains((string) $name)) {
91 18
            throw new ArgumentNotProvided($this->arguments->get((string) $name));
92
        }
93
94 15
        return $this->values->get((string) $name);
95
    }
96
97
    /**
98
     * @return SetInterface<Argument>
99
     */
100 14
    public function all(): SetInterface
101
    {
102 14
        return Set::of(Argument::class, ...$this->arguments->values());
103
    }
104
}
105