Passed
Push — main ( 3c3dd7...47074e )
by Thomas
13:06
created

Entry::getConstructor()   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
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Conia\Chuck\Di;
6
7
use Closure;
8
use Conia\Chuck\Exception\ContainerException;
9
10
/**
11
 * @psalm-type Args array<string|mixed>|Closure(): array<string|mixed>
12
 */
13
class Entry
14
{
15
    /** @psalm-var null|Args */
16
    protected array|Closure|null $args = null;
17
    protected ?string $constructor = null;
18
    protected bool $asIs = false;
19
    protected bool $reify;
20
    protected mixed $instance = null;
21
22
    /** @psalm-var list<Call> */
23
    protected array $calls = [];
24
25
    /**
26
     * @psalm-param non-empty-string $id
27
     * */
28 167
    public function __construct(
29
        readonly protected string $id,
30
        protected mixed $definition
31
    ) {
32 167
        $this->reify = $this->negotiateReify($definition);
33
    }
34
35 2
    public function reify(bool $reify = true): static
36
    {
37 2
        $this->reify = $reify;
38
39 2
        return $this;
40
    }
41
42 100
    public function shouldReify(): bool
43
    {
44 100
        return $this->reify;
45
    }
46
47 3
    public function asIs(bool $asIs = true): static
48
    {
49
        // An update call is unecessary
50 3
        if ($asIs) {
51 3
            $this->reify = false;
52
        }
53
54 3
        $this->asIs = $asIs;
55
56 3
        return $this;
57
    }
58
59 107
    public function shouldReturnAsIs(): bool
60
    {
61 107
        return $this->asIs;
62
    }
63
64 135
    public function args(mixed ...$args): static
65
    {
66 135
        $numArgs = count($args);
67
68 135
        if ($numArgs === 1) {
69 7
            if (is_string(array_key_first($args))) {
70
                /** @psalm-var Args */
71 1
                $this->args = $args;
72 6
            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
73
                /** @psalm-var Args */
74 5
                $this->args = $args[0];
75
            } else {
76 7
                throw new ContainerException(
77 7
                    'Registry entry arguments can be passed as a single associative array, ' .
78 7
                    'as named arguments, or as a Closure'
79 7
                );
80
            }
81 130
        } elseif ($numArgs > 1) {
82 130
            if (!is_string(array_key_first($args))) {
83 1
                throw new ContainerException(
84 1
                    'Registry entry arguments can be passed as a single associative array, ' .
85 1
                    'as named arguments, or as a Closure'
86 1
                );
87
            }
88
89 129
            $this->args = $args;
90
        }
91
92 133
        return $this;
93
    }
94
95 100
    public function getArgs(): array|Closure|null
96
    {
97 100
        return $this->args;
98
    }
99
100 128
    public function constructor(string $methodName): static
101
    {
102 128
        $this->constructor = $methodName;
103
104 128
        return $this;
105
    }
106
107 95
    public function getConstructor(): ?string
108
    {
109 95
        return $this->constructor;
110
    }
111
112 2
    public function call(string $method, mixed ...$args): static
113
    {
114 2
        $this->calls[] = new Call($method, ...$args);
115
116 2
        return $this;
117
    }
118
119
    /** @psalm-return list<Call> */
120 99
    public function getCalls(): array
121
    {
122 99
        return $this->calls;
123
    }
124
125 10
    public function definition(): mixed
126
    {
127 10
        return $this->definition;
128
    }
129
130 3
    public function instance(): mixed
131
    {
132 3
        return $this->instance;
133
    }
134
135 106
    public function get(): mixed
136
    {
137 106
        return $this->instance ?? $this->definition;
138
    }
139
140 98
    public function set(mixed $instance): void
141
    {
142 98
        $this->instance = $instance;
143
    }
144
145 167
    protected function negotiateReify(mixed $definition): bool
146
    {
147 167
        if (is_string($definition)) {
148 147
            if (is_callable($definition)) {
149 1
                return true;
150
            }
151
152 147
            if (!class_exists($definition)) {
153 147
                return false;
154
            }
155 165
        } elseif ($definition instanceof Closure) {
156 103
            return true;
157
        } else {
158 165
            if (is_scalar($definition) || is_array($definition) || is_object($definition)) {
159 165
                return false;
160
            }
161
        }
162
163 146
        return true;
164
    }
165
}
166