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

Dependency::name()   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\Definition;
5
6
use Innmind\Compose\{
7
    Definition\Dependency\Parameter,
8
    Definition\Service\Argument,
9
    Services,
10
    Lazy,
11
    Exception\ReferenceNotFound,
12
    Exception\ArgumentNotExtractable
13
};
14
use Innmind\Immutable\{
15
    Set,
16
    MapInterface,
17
    Map,
18
    StreamInterface
19
};
20
21
final class Dependency
22
{
23
    private $name;
24
    private $services;
25
    private $parameters;
26
27 56
    public function __construct(
28
        Name $name,
29
        Services $services,
30
        Parameter ...$parameters
31
    ) {
32 56
        $this->name = $name;
33 56
        $this->services = $services;
34 56
        $this->parameters = Set::of(Parameter::class, ...$parameters);
35 56
    }
36
37 35
    public function name(): Name
38
    {
39 35
        return $this->name;
40
    }
41
42 8
    public function bind(Services $services): self
43
    {
44
        $parameters = $this
45 8
            ->parameters
46 8
            ->reduce(
47 8
                new Map('string', 'mixed'),
48 8
                static function(Map $parameters, Parameter $parameter) use ($services): Map {
49 8
                    return $parameters->put(
50 8
                        (string) $parameter->name(),
51 8
                        $parameter->resolve($services)
52
                    );
53 8
                }
54
            );
55
56 8
        $self = clone $this;
57 8
        $self->services = $self->services->inject($parameters);
58
59 8
        return $self;
60
    }
61
62 21
    public function lazy(Name $name): Lazy
63
    {
64 21
        if (!$this->has($name)) {
65 7
            throw new ReferenceNotFound((string) $name);
66
        }
67
68 14
        return new Lazy(
69 14
            $name,
70 14
            $this->services
71
        );
72
    }
73
74 5
    public function build(Name $name): object
75
    {
76 5
        return $this->lazy($name)->load();
77
    }
78
79 45
    public function has(Name $name): bool
80
    {
81 45
        if (!$this->services->has($name)) {
82 6
            return false;
83
        }
84
85 40
        $service = $this->services->get($name);
86
87 40
        if (!$service->exposed() || !$service->isExposedAs($name)) {
88 12
            return false;
89
        }
90
91 29
        return true;
92
    }
93
94 5
    public function dependsOn(self $other): bool
95
    {
96 5
        return $this->parameters->reduce(
97 5
            false,
98 5
            function(bool $dependsOn, Parameter $parameter) use ($other): bool {
99 3
                return $dependsOn || $parameter->refersTo($other);
100 5
            }
101
        );
102
    }
103
104 11
    public function decorate(
105
        Name $decorator,
106
        Name $decorated,
107
        Name $newName = null
108
    ): Service {
109 11
        if (!$this->has($decorator)) {
110 4
            throw new ReferenceNotFound((string) $decorator);
111
        }
112
113 7
        $service = $this->services->get($decorator);
114
115 7
        return $service->tunnel($this->name, $decorated, $newName);
116
    }
117
118
    /**
119
     * @param StreamInterface<mixed> $arguments
120
     *
121
     * @return StreamInterface<mixed>
122
     */
123 11
    public function extract(
124
        Name $name,
125
        StreamInterface $arguments,
126
        Argument $argument
127
    ): StreamInterface {
128 11
        if (!$this->has($name)) {
129 5
            throw new ReferenceNotFound((string) $name);
130
        }
131
132 6
        $service = $this->services->get($name);
133
134
        if (
135 6
            !$service->decorates() ||
136 6
            !$service->arguments()->contains($argument)
137
        ) {
138 2
            throw new ArgumentNotExtractable;
139
        }
140
141 4
        return $argument->resolve(
142 4
            $arguments,
143 4
            $this->services
144
        );
145
    }
146
147
    /**
148
     * The list of exposed services name with their constructor
149
     *
150
     * @return MapInterface<Name, Constructor>
151
     */
152 3
    public function exposed(): MapInterface
153
    {
154 3
        return $this->services->exposed();
155
    }
156
}
157