OptionParameter::withValidValues()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Valkyrja\Cli\Routing\Data;
15
16
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Valkyrja\Cli\Interaction\Option\Contract\OptionContract;
18
use Valkyrja\Cli\Routing\Data\Abstract\Parameter;
19
use Valkyrja\Cli\Routing\Data\Contract\OptionParameterContract;
20
use Valkyrja\Cli\Routing\Enum\OptionMode;
21
use Valkyrja\Cli\Routing\Enum\OptionValueMode;
22
use Valkyrja\Cli\Routing\Throwable\Exception\InvalidArgumentException;
23
use Valkyrja\Type\Data\Cast;
24
25
use function count;
26
use function in_array;
27
28
class OptionParameter extends Parameter implements OptionParameterContract
29
{
30
    /**
31
     * @param non-empty-string      $name             The names
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
32
     * @param non-empty-string      $description      The description
33
     * @param non-empty-string|null $valueDisplayName The value display name
34
     * @param non-empty-string|null $defaultValue     The default value
35
     * @param non-empty-string[]    $shortNames       The short names
36
     * @param non-empty-string[]    $validValues      The valid values
37
     * @param OptionContract[]      $options          The options
38
     */
39
    public function __construct(
40
        string $name,
41
        string $description,
42
        protected string|null $valueDisplayName = null,
43
        Cast|null $cast = null,
44
        protected string|null $defaultValue = null,
45
        protected array $shortNames = [],
46
        protected array $validValues = [],
47
        protected array $options = [],
48
        protected OptionMode $mode = OptionMode::OPTIONAL,
49
        protected OptionValueMode $valueMode = OptionValueMode::DEFAULT,
50
    ) {
51
        parent::__construct(
52
            name: $name,
53
            description: $description,
54
            cast: $cast
55
        );
56
    }
57
58
    /**
59
     * @inheritDoc
60
     */
61
    #[Override]
62
    public function getShortNames(): array
63
    {
64
        return $this->shortNames;
65
    }
66
67
    /**
68
     * @inheritDoc
69
     */
70
    #[Override]
71
    public function withShortNames(string ...$shortNames): static
72
    {
73
        $new = clone $this;
74
75
        $new->shortNames = $shortNames;
76
77
        return $new;
78
    }
79
80
    /**
81
     * @inheritDoc
82
     */
83
    #[Override]
84
    public function withAddedShortNames(string ...$shortNames): static
85
    {
86
        $new = clone $this;
87
88
        foreach ($shortNames as $shortName) {
89
            if (! in_array($shortName, $new->shortNames, true)) {
90
                $new->shortNames[] = $shortName;
91
            }
92
        }
93
94
        return $new;
95
    }
96
97
    /**
98
     * @inheritDoc
99
     */
100
    #[Override]
101
    public function getMode(): OptionMode
102
    {
103
        return $this->mode;
104
    }
105
106
    /**
107
     * @inheritDoc
108
     */
109
    #[Override]
110
    public function withMode(OptionMode $mode): static
111
    {
112
        $new = clone $this;
113
114
        $new->mode = $mode;
115
116
        return $new;
117
    }
118
119
    /**
120
     * @inheritDoc
121
     */
122
    #[Override]
123
    public function getValueMode(): OptionValueMode
124
    {
125
        return $this->valueMode;
126
    }
127
128
    /**
129
     * @inheritDoc
130
     */
131
    #[Override]
132
    public function withValueMode(OptionValueMode $valueMode): static
133
    {
134
        $new = clone $this;
135
136
        $new->valueMode = $valueMode;
137
138
        return $new;
139
    }
140
141
    /**
142
     * @inheritDoc
143
     */
144
    #[Override]
145
    public function getValueDisplayName(): string|null
146
    {
147
        return $this->valueDisplayName;
148
    }
149
150
    /**
151
     * @inheritDoc
152
     */
153
    #[Override]
154
    public function withValueDisplayName(string|null $valueName): static
155
    {
156
        $new = clone $this;
157
158
        $new->valueDisplayName = $valueName;
159
160
        return $new;
161
    }
162
163
    /**
164
     * @inheritDoc
165
     */
166
    #[Override]
167
    public function getValidValues(): array
168
    {
169
        return $this->validValues;
170
    }
171
172
    /**
173
     * @inheritDoc
174
     */
175
    #[Override]
176
    public function withValidValues(string ...$validValues): static
177
    {
178
        $new = clone $this;
179
180
        $new->validValues = $validValues;
181
182
        return $new;
183
    }
184
185
    /**
186
     * @inheritDoc
187
     */
188
    #[Override]
189
    public function withAddedValidValues(string ...$validValues): static
190
    {
191
        $new = clone $this;
192
193
        foreach ($validValues as $validValue) {
194
            if (! in_array($validValue, $new->validValues, true)) {
195
                $new->validValues[] = $validValue;
196
            }
197
        }
198
199
        return $new;
200
    }
201
202
    /**
203
     * @inheritDoc
204
     */
205
    #[Override]
206
    public function getDefaultValue(): string|null
207
    {
208
        return $this->defaultValue;
209
    }
210
211
    /**
212
     * @inheritDoc
213
     */
214
    #[Override]
215
    public function withDefaultValue(string|null $defaultValue = null): static
216
    {
217
        $new = clone $this;
218
219
        $new->defaultValue = $defaultValue;
220
221
        return $new;
222
    }
223
224
    /**
225
     * @inheritDoc
226
     */
227
    #[Override]
228
    public function getOptions(): array
229
    {
230
        return $this->options;
231
    }
232
233
    /**
234
     * @inheritDoc
235
     */
236
    #[Override]
237
    public function withOptions(OptionContract ...$options): static
238
    {
239
        $new = clone $this;
240
241
        $new->options = [];
242
243
        foreach ($options as $option) {
244
            if ($this->valueMode === OptionValueMode::NONE && $option->getValue() !== null) {
245
                throw new InvalidArgumentException("$this->name should have no value");
246
            }
247
248
            $new->options[] = $option;
249
        }
250
251
        return $new;
252
    }
253
254
    /**
255
     * @inheritDoc
256
     */
257
    #[Override]
258
    public function withAddedOptions(OptionContract ...$options): static
259
    {
260
        $new = clone $this;
261
262
        foreach ($options as $option) {
263
            if ($this->valueMode === OptionValueMode::NONE && $option->getValue() !== null) {
264
                throw new InvalidArgumentException("$this->name should have no value");
265
            }
266
267
            $new->options[] = $option;
268
        }
269
270
        return $new;
271
    }
272
273
    /**
274
     * @inheritDoc
275
     */
276
    #[Override]
277
    public function getCastValues(): array
278
    {
279
        $values   = [];
280
        $cast     = $this->cast;
281
        $castType = $cast->type ?? null;
282
283
        foreach ($this->options as $option) {
284
            if ($cast === null || $castType === null) {
285
                $values[] = $option->getValue();
286
287
                continue;
288
            }
289
290
            $value = $castType::fromValue($option->getValue());
291
292
            if ($cast->convert) {
293
                /** @psalm-suppress MixedAssignment */
294
                $values[] = $value->asValue();
295
296
                continue;
297
            }
298
299
            $values[] = $value;
300
        }
301
302
        return $values;
303
    }
304
305
    /**
306
     * @inheritDoc
307
     */
308
    #[Override]
309
    public function getFirstValue(): string|null
310
    {
311
        $firstItem = $this->options[0] ?? null;
312
313
        return $firstItem?->getValue();
314
    }
315
316
    /**
317
     * @inheritDoc
318
     */
319
    #[Override]
320
    public function areValuesValid(): bool
321
    {
322
        $valid = true;
323
324
        if ($this->mode === OptionMode::REQUIRED) {
325
            $valid = $this->options !== [];
326
        }
327
328
        if ($this->valueMode === OptionValueMode::DEFAULT) {
329
            $valid = $valid && count($this->options) <= 1;
330
        }
331
332
        return $valid;
333
    }
334
335
    /**
336
     * @inheritDoc
337
     */
338
    #[Override]
339
    public function validateValues(): static
340
    {
341
        if (! $this->areValuesValid()) {
342
            throw new InvalidArgumentException("$this->name is required");
343
        }
344
345
        return $this;
346
    }
347
}
348