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