Passed
Push — master ( 95373b...dd07b4 )
by Nate
43s
created

JsonElementWriter::setSerializeNull()   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
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/*
3
 * Copyright (c) Nate Brunette.
4
 * Distributed under the MIT License (http://opensource.org/licenses/MIT)
5
 */
6
7
declare(strict_types=1);
8
9
namespace Tebru\Gson\Internal;
10
11
use JsonSerializable;
12
use Tebru\Gson\Element\JsonArray;
13
use Tebru\Gson\Element\JsonElement;
14
use Tebru\Gson\Element\JsonNull;
15
use Tebru\Gson\Element\JsonObject;
16
use Tebru\Gson\Element\JsonPrimitive;
17
use Tebru\Gson\JsonWritable;
18
19
/**
20
 * Class JsonElementWriter
21
 *
22
 * @author Nate Brunette <[email protected]>
23
 */
24
final class JsonElementWriter extends JsonWriter implements JsonSerializable
25
{
26
    /**
27
     * Begin writing array
28
     *
29
     * @return JsonWritable
30
     * @throws \LogicException
31
     */
32 20
    public function beginArray(): JsonWritable
33
    {
34 20
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
35 1
            $this->assertionFailed('Cannot call beginArray() before name() during object serialization');
36
        }
37
38 19
        $array = new JsonArray();
39 19
        $this->push($array);
40 19
        $this->stack[] = $array;
41 19
        $this->stackStates[$this->stackSize] = self::STATE_ARRAY;
42 19
        $this->stackSize++;
43 19
        $this->pathIndices[$this->pathIndex++]++;
44 19
        $this->pathIndices[$this->pathIndex] = -1;
45
46 19
        return $this;
47
    }
48
49
    /**
50
     * End writing array
51
     *
52
     * @return JsonWritable
53
     * @throws \LogicException
54
     */
55 7
    public function endArray(): JsonWritable
56
    {
57 7
        if ($this->stackSize === 0 || $this->stackStates[$this->stackSize - 1] !== self::STATE_ARRAY) {
58 3
            $this->assertionFailed('Cannot call endArray() if not serializing array');
59
        }
60
61 5
        \array_pop($this->stack);
62 5
        $this->stackSize--;
63 5
        $this->pathIndex--;
64
65 5
        return $this;
66
    }
67
68
    /**
69
     * Begin writing object
70
     *
71
     * @return JsonWritable
72
     * @throws \LogicException
73
     */
74 32
    public function beginObject(): JsonWritable
75
    {
76 32
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
77 1
            $this->assertionFailed('Cannot call beginObject() before name() during object serialization');
78
        }
79
80 32
        $class = new JsonObject();
81 32
        $this->push($class);
82 32
        $this->stack[$this->stackSize] = $class;
83 32
        $this->stackStates[$this->stackSize] = self::STATE_OBJECT_NAME;
84 32
        $this->stackSize++;
85 32
        $this->pathIndices[$this->pathIndex++]++;
86 32
        $this->pathIndices[$this->pathIndex] = -1;
87
88 32
        return $this;
89
    }
90
91
    /**
92
     * End writing object
93
     *
94
     * @return JsonWritable
95
     * @throws \LogicException
96
     */
97 10
    public function endObject(): JsonWritable
98
    {
99 10
        if ($this->stackSize === 0 || $this->stackStates[$this->stackSize - 1] !== self::STATE_OBJECT_NAME) {
100 2
            $this->assertionFailed('Cannot call endObject() if not serializing object');
101
        }
102
103 8
        \array_pop($this->stack);
104 8
        $this->stackSize--;
105 8
        $this->pathNames[$this->pathIndex--] = null;
106
107 8
        return $this;
108
    }
109
110
    /**
111
     * Write an integer value
112
     *
113
     * @param int $value
114
     * @return JsonWritable
115
     * @throws \LogicException
116
     */
117 16
    public function writeInteger(int $value): JsonWritable
118
    {
119 16
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
120 1
            $this->assertionFailed('Cannot call writeInteger() before name() during object serialization');
121
        }
122
123 15
        $this->pathIndices[$this->pathIndex]++;
124
125 15
        return $this->push(JsonPrimitive::create($value));
126
    }
127
128
    /**
129
     * Write a float value
130
     *
131
     * @param float $value
132
     * @return JsonWritable
133
     * @throws \LogicException
134
     */
135 4
    public function writeFloat(float $value): JsonWritable
136
    {
137 4
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
138 1
            $this->assertionFailed('Cannot call writeFloat() before name() during object serialization');
139
        }
140
141 3
        $this->pathIndices[$this->pathIndex]++;
142
143 3
        return $this->push(JsonPrimitive::create($value));
144
    }
145
146
    /**
147
     * Write a string value
148
     *
149
     * @param string $value
150
     * @return JsonWritable
151
     * @throws \LogicException
152
     */
153 8
    public function writeString(string $value): JsonWritable
154
    {
155 8
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
156 1
            $this->assertionFailed('Cannot call writeString() before name() during object serialization');
157
        }
158
159 7
        $this->pathIndices[$this->pathIndex]++;
160
161 7
        return $this->push(JsonPrimitive::create($value));
162
    }
163
164
    /**
165
     * Write a boolean value
166
     *
167
     * @param boolean $value
168
     * @return JsonWritable
169
     * @throws \LogicException
170
     */
171 5
    public function writeBoolean(bool $value): JsonWritable
172
    {
173 5
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
174 1
            $this->assertionFailed('Cannot call writeBoolean() before name() during object serialization');
175
        }
176
177 4
        $this->pathIndices[$this->pathIndex]++;
178
179 4
        return $this->push(JsonPrimitive::create($value));
180
    }
181
182
    /**
183
     * Write a null value if we are serializing nulls, otherwise
184
     * skip the value.  If this is a property value, that property
185
     * should be skipped as well.
186
     *
187
     * @return JsonWritable
188
     * @throws \LogicException
189
     */
190 9
    public function writeNull(): JsonWritable
191
    {
192 9
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
193 1
            $this->assertionFailed('Cannot call writeNull() before name() during object serialization');
194
        }
195
196 8
        if ($this->serializeNull) {
197 4
            $this->pathIndices[$this->pathIndex]++;
198 4
            return $this->push(new JsonNull());
199
        }
200
201
        // if we're not serializing nulls
202 4
        if (null !== $this->pendingName) {
203 2
            $this->stackStates[$this->stackSize - 1] = self::STATE_OBJECT_NAME;
204 2
            $this->pendingName = null;
205
        }
206
207 4
        return $this;
208
    }
209
210
    /**
211
     * Specify data which should be serialized to JSON
212
     *
213
     * @return mixed
214
     */
215 17
    public function jsonSerialize()
216
    {
217 17
        if (null === $this->result) {
218 1
            return null;
219
        }
220
221 16
        return $this->result->jsonSerialize();
222
    }
223
224
    /**
225
     * Get the result as a json element
226
     *
227
     * @return JsonElement
228
     */
229 1
    public function toJsonElement(): JsonElement
230
    {
231 1
        return $this->result;
232
    }
233
234
    /**
235
     * Push a value to the result or current array/object
236
     *
237
     * @param JsonElement $value
238
     * @return JsonWritable
239
     * @throws \LogicException
240
     */
241 56
    private function push(JsonElement $value): JsonWritable
242
    {
243 56
        if (0 === $this->stackSize) {
244 56
            if (null !== $this->result) {
245 2
                $this->assertionFailed('Attempting to write two different types');
246
            }
247
248 56
            $this->result = $value;
249
250 56
            return $this;
251
        }
252
253 25
        switch ($this->stackStates[$this->stackSize - 1]) {
254 25
            case self::STATE_OBJECT_VALUE:
255
                /** @var JsonObject $element */
256 14
                $element = $this->stack[$this->stackSize - 1];
257 14
                $element->add($this->pendingName, $value);
258 14
                $this->stackStates[$this->stackSize - 1] = self::STATE_OBJECT_NAME;
259 14
                $this->pendingName = null;
260 14
                break;
261 14
            case self::STATE_ARRAY:
262
                /** @var JsonArray $element */
263 14
                $element = $this->stack[$this->stackSize - 1];
264 14
                $element->addJsonElement($value);
265 14
                $this->stackStates[$this->stackSize - 1] = self::STATE_ARRAY;
266 14
                break;
267
        }
268
269 25
        return $this;
270
    }
271
}
272