Passed
Pull Request — master (#54)
by Frank
04:59
created

DefinitionGroup   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 186
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 53
c 2
b 0
f 0
dl 0
loc 186
ccs 58
cts 58
cp 1
rs 10
wmc 22
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EventSauce\EventSourcing\CodeGeneration;
6
7
use EventSauce\EventSourcing\PointInTime;
8
9
final class DefinitionGroup
10
{
11
    /**
12
     * @var string
13
     */
14
    private $namespace;
15
16
    /**
17
     * @var PayloadDefinition[]
18
     */
19
    private $events = [];
20
21
    /**
22
     * @var array
23
     */
24
    private $defaults = [];
25
26
    /**
27
     * @var array
28
     */
29
    private $typeSerializer = [
30
        'string' => '({type}) {param}',
31
        'array' => '({type}) {param}',
32
        'integer' => '({type}) {param}',
33
        'int' => '({type}) {param}',
34
        'bool' => '({type}) {param}',
35
        'float' => '({type}) {param}',
36
    ];
37
38
    /**
39
     * @var array
40
     */
41
    private $typeDeserializer = [
42
        'string' => '({type}) {param}',
43
        'array' => '({type}) {param}',
44
        'integer' => '({type}) {param}',
45
        'int' => '({type}) {param}',
46
        'bool' => '({type}) {param}',
47
        'float' => '({type}) {param}',
48
    ];
49
50
    /**
51
     * @var array
52
     */
53
    private $fieldSerializer = [];
54
55
    /**
56
     * @var array
57
     */
58
    private $fieldDeserializer = [];
59
60
    /**
61
     * @var PayloadDefinition[]
62
     */
63
    private $commands = [];
64
65
    /**
66
     * @var string[]
67
     */
68
    private $typeAliases = [];
69
70
    public function __construct()
71
    {
72
        $this->typeSerializer(PointInTime::class, '{param}->toString()');
73
        $this->typeDeserializer(PointInTime::class, '{type}::fromString({param})');
74
    }
75
76
    public static function create(string $namespace): DefinitionGroup
77
    {
78
        return (new DefinitionGroup())->withNamespace($namespace);
79
    }
80
81
    public function withNamespace(string $namespace): DefinitionGroup
82
    {
83
        $this->namespace = $namespace;
84
85
        return $this;
86
    }
87
88
    public function typeSerializer(string $type, string $template)
89
    {
90
        $type = $this->resolveTypeAlias($type);
91
92
        $this->typeSerializer[TypeNormalizer::normalize($type)] = $template;
93
    }
94
95
    public function serializerForType($type)
96
    {
97
        $type = $this->resolveTypeAlias($type);
98
99
        return $this->typeSerializer[$type] ?? 'new {type}({param})';
100
    }
101
102
    public function typeDeserializer(string $type, string $template)
103
    {
104
        $type = $this->resolveTypeAlias($type);
105
106
        $this->typeDeserializer[TypeNormalizer::normalize($type)] = $template;
107
    }
108
109
    public function deserializerForType($type)
110
    {
111
        $type = $this->resolveTypeAlias($type);
112
113
        return $this->typeDeserializer[$type] ?? 'new {type}({param})';
114
    }
115
116
    public function fieldSerializer(string $field, string $template)
117
    {
118
        $this->fieldSerializer[$field] = $template;
119
    }
120
121
    public function serializerForField($field)
122
    {
123
        return $this->fieldSerializer[$field] ?? null;
124
    }
125
126
    public function fieldDeserializer(string $field, string $template)
127
    {
128
        $this->fieldDeserializer[$field] = $template;
129
    }
130
131
    public function deserializerForField($field)
132
    {
133
        return $this->fieldDeserializer[$field] ?? null;
134
    }
135
136
    public function fieldDefault(string $name, string $type, string $example = null)
137
    {
138
        $type = $this->resolveTypeAlias($type);
139
        $this->defaults[$name] = compact('type', 'example');
140
    }
141
142
    public function aliasType(string $alias, string $type)
143
    {
144
        $this->typeAliases[$alias] = TypeNormalizer::normalize($type);
145
    }
146
147
    public function resolveTypeAlias(string $alias = null)
148
    {
149
        while (isset($this->typeAliases[$alias])) {
150
            $alias = $this->typeAliases[$alias];
151
        }
152
153
        return $alias;
154
    }
155
156
    public function event(string $name): PayloadDefinition
157
    {
158
        return $this->events[] = new PayloadDefinition($this, $name);
159
    }
160
161
    public function command(string $name)
162
    {
163
        return $this->commands[] = new PayloadDefinition($this, $name);
164
    }
165
166
    public function typeForField(string $field): string
167
    {
168
        return $this->defaults[$field]['type'] ?? 'string';
169
    }
170
171
    public function exampleForField(string $field)
172
    {
173
        return $this->defaults[$field]['example'] ?? null;
174
    }
175
176
    /**
177
     * @return PayloadDefinition[]
178
     */
179
    public function events(): array
180
    {
181
        return $this->events;
182
    }
183
184
    /**
185
     * @return PayloadDefinition[]
186
     */
187
    public function commands(): array
188
    {
189
        return $this->commands;
190
    }
191
192
    public function namespace(): string
193
    {
194
        return $this->namespace;
195
    }
196
}
197