Passed
Push — main ( d72029...35e57d )
by Thomas
03:10
created

Entry::negotiateReify()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 7

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 15
ccs 9
cts 9
cp 1
rs 8.8333
c 0
b 0
f 0
cc 7
nc 5
nop 1
crap 7
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Conia\Chuck\Registry;
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 bool $asIs = false;
18
    protected bool $reify;
19
    protected mixed $instance = null;
20
21
    /**
22
     * @psalm-param non-empty-string $id
23
     * */
24 126
    public function __construct(
25
        readonly protected string $id,
26
        protected mixed $definition
27
    ) {
28 126
        $this->reify = $this->negotiateReify($definition);
29
    }
30
31 65
    public function shouldReify(): bool
32
    {
33 65
        return $this->reify;
34
    }
35
36 73
    public function shouldReturnAsIs(): bool
37
    {
38 73
        return $this->asIs;
39
    }
40
41 66
    public function getArgs(): array|Closure|null
42
    {
43 66
        return $this->args;
44
    }
45
46 1
    public function reify(bool $reify = true): self
47
    {
48 1
        $this->reify = $reify;
49
50 1
        return $this;
51
    }
52
53 87
    public function asIs(bool $asIs = true): self
54
    {
55
        // An update call is unecessary
56 87
        if ($asIs) {
57 87
            $this->reify = false;
58
        }
59
60 87
        $this->asIs = $asIs;
61
62 87
        return $this;
63
    }
64
65 12
    public function args(mixed ...$args): self
66
    {
67 12
        $numArgs = count($args);
68
69 12
        if ($numArgs === 1) {
70 7
            if (is_string(array_key_first($args))) {
71
                /** @psalm-var Args */
72 1
                $this->args = $args;
73 6
            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
74
                /** @psalm-var Args */
75 5
                $this->args = $args[0];
76
            } else {
77 7
                throw new ContainerException(
78 7
                    'Registry entry arguments can be passed as a single associative array, ' .
79 7
                    'as named arguments, or as a Closure'
80 7
                );
81
            }
82 5
        } elseif ($numArgs > 1) {
83 5
            if (!is_string(array_key_first($args))) {
84 1
                throw new ContainerException(
85 1
                    'Registry entry arguments can be passed as a single associative array, ' .
86 1
                    'as named arguments, or as a Closure'
87 1
                );
88
            }
89
90 4
            $this->args = $args;
91
        }
92
93 10
        return $this;
94
    }
95
96 23
    public function definition(): mixed
97
    {
98 23
        return $this->definition;
99
    }
100
101 3
    public function instance(): mixed
102
    {
103 3
        return $this->instance;
104
    }
105
106 72
    public function get(): mixed
107
    {
108 72
        return $this->instance ?? $this->definition;
109
    }
110
111 65
    public function set(mixed $instance): void
112
    {
113 65
        $this->instance = $instance;
114
    }
115
116 126
    protected function negotiateReify(mixed $definition): bool
117
    {
118 126
        if (is_string($definition)) {
119 103
            if (!class_exists($definition)) {
120 103
                return false;
121
            }
122 125
        } elseif ($definition instanceof Closure) {
123 29
            return true;
124
        } else {
125 125
            if (is_scalar($definition) || is_array($definition) || is_object($definition)) {
126 125
                return false;
127
            }
128
        }
129
130 102
        return true;
131
    }
132
}
133