TypeScript::formatCases()   A
last analyzed

Complexity

Conditions 3
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 10
ccs 6
cts 6
cp 1
crap 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cerbero\Enum\Services;
6
7
use Cerbero\Enum\Enums;
8
use UnitEnum;
0 ignored issues
show
Bug introduced by
The type UnitEnum 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...
9
10
use function Cerbero\Enum\className;
11
use function Cerbero\Enum\ensureParentDirectory;
12
13
/**
14
 * The TypeScript service.
15
 */
16
class TypeScript
17
{
18
    /**
19
     * The TypeScript enums path.
20
     */
21
    protected string $path;
22
23
    /**
24
     * Instantiate the class.
25
     *
26
     * @param class-string<UnitEnum> $enum
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<UnitEnum> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<UnitEnum>.
Loading history...
27
     */
28 6
    public function __construct(protected string $enum)
29
    {
30 6
        $this->path = Enums::basePath(Enums::typeScript($enum));
31
    }
32
33
    /**
34
     * Synchronize the enum in TypeScript.
35
     */
36 6
    public function sync(bool $overwrite = false): bool
37
    {
38
        return match (true) {
39 6
            ! file_exists($this->path) => $this->createEnum(),
40 2
            $this->enumIsMissing() => $this->appendEnum(),
41 1
            $overwrite => $this->replaceEnum(),
42 6
            default => true,
43
        };
44
    }
45
46
    /**
47
     * Create the TypeScript file for the enum.
48
     */
49 6
    protected function createEnum(): bool
50
    {
51 6
        ensureParentDirectory($this->path);
52
53 6
        return file_put_contents($this->path, $this->transform()) !== false;
54
    }
55
56
    /**
57
     * Append the enum to the TypeScript file.
58
     */
59 2
    protected function appendEnum(): bool
60
    {
61 2
        return file_put_contents($this->path, PHP_EOL . $this->transform(), flags: FILE_APPEND) !== false;
62
    }
63
64
    /**
65
     * Retrieved the enum transformed for TypeScript.
66
     */
67 6
    public function transform(): string
68
    {
69 6
        $stub = (string) file_get_contents($this->stub());
70
71 6
        return strtr($stub, $this->replacements());
72
    }
73
74
    /**
75
     * Retrieve the path of the stub.
76
     */
77 6
    protected function stub(): string
78
    {
79 6
        return __DIR__ . '/../../stubs/typescript.stub';
80
    }
81
82
    /**
83
     * Retrieve the stub replacements.
84
     *
85
     * @return array<string, string>
86
     */
87 6
    protected function replacements(): array
88
    {
89 6
        return [
90 6
            '{{ name }}' => className($this->enum),
91 6
            '{{ cases }}' => $this->formatCases(),
92 6
        ];
93
    }
94
95
    /**
96
     * Retrieve the enum cases formatted as a string
97
     */
98 6
    protected function formatCases(): string
99
    {
100 6
        $cases = array_map(function (UnitEnum $case) {
101
            /** @var string|int|null $value */
102 5
            $value = is_string($value = $case->value ?? null) ? "'{$value}'" : $value;
103
104 5
            return "    {$case->name}" . ($value === null ? ',' : " = {$value},");
105 6
        }, $this->enum::cases());
106
107 6
        return implode(PHP_EOL, $cases);
108
    }
109
110
    /**
111
     * Determine whether the enum is missing.
112
     */
113 2
    protected function enumIsMissing(): bool
114
    {
115 2
        $name = className($this->enum);
116
117 2
        return preg_match("~^export enum {$name}~im", (string) file_get_contents($this->path)) === 0;
118
    }
119
120
    /**
121
     * Replace the enum in the TypeScript file.
122
     */
123 1
    protected function replaceEnum(): bool
124
    {
125 1
        $name = className($this->enum);
126 1
        $oldContent = (string) file_get_contents($this->path);
127 1
        $newContent = preg_replace("~^(export enum {$name}[^}]+})~im", trim($this->transform()), $oldContent);
128
129 1
        return file_put_contents($this->path, $newContent) !== false;
130
    }
131
}
132