Completed
Push — caching ( 6c9b2f )
by Nate
03:39
created

TypedArrayTypeAdapter::read()   B

Complexity

Conditions 8
Paths 6

Size

Total Lines 33
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 19
c 1
b 0
f 0
dl 0
loc 33
rs 8.4444
cc 8
nc 6
nop 2
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\TypeAdapter;
10
11
use Tebru\Gson\Context\ReaderContext;
12
use Tebru\Gson\Context\WriterContext;
13
use Tebru\Gson\Exception\JsonSyntaxException;
14
use Tebru\Gson\TypeAdapter;
15
16
/**
17
 * Class TypedArrayTypeAdapter
18
 *
19
 * @author Nate Brunette <[email protected]>
20
 */
21
class TypedArrayTypeAdapter extends TypeAdapter
22
{
23
    /**
24
     * @var TypeAdapter
25
     */
26
    protected $valueTypeAdapter;
27
28
    /**
29
     * @var bool
30
     */
31
    private $stringKeys;
32
33
    /**
34
     * Constructor
35
     *
36
     * @param TypeAdapter $valueTypeAdapter
37
     * @param bool $stringKeys
38
     */
39
    public function __construct(TypeAdapter $valueTypeAdapter, bool $stringKeys)
40
    {
41
        $this->valueTypeAdapter = $valueTypeAdapter;
42
        $this->stringKeys = $stringKeys;
43
    }
44
45
    /**
46
     * Read the next value, convert it to its type and return it
47
     *
48
     * @param array|null $value
49
     * @param ReaderContext $context
50
     * @return array|null
51
     */
52
    public function read($value, ReaderContext $context): ?array
53
    {
54
        if ($value === null) {
55
            return null;
56
        }
57
58
        if (!is_array($value)) {
0 ignored issues
show
introduced by
The condition is_array($value) is always true.
Loading history...
59
            throw new JsonSyntaxException(sprintf('Could not parse json, expected array or object but found "%s"', gettype($value)));
60
        }
61
62
        $result = [];
63
        $arrayIsObject = is_string(key($value));
64
65
        if ($arrayIsObject !== $this->stringKeys) {
66
            throw new JsonSyntaxException(
67
                sprintf(
68
                    'Expected %s, but found %s for key',
69
                    $this->stringKeys ? 'string' : 'integer',
70
                    $arrayIsObject ? 'string' : 'integer'
71
                )
72
            );
73
        }
74
75
        foreach ($value as $key => $item) {
76
            $itemValue = $this->valueTypeAdapter->read($item, $context);
77
            if ($this->stringKeys) {
78
                $result[(string)$key] = $itemValue;
79
            } else {
80
                $result[] = $itemValue;
81
            }
82
        }
83
84
        return $result;
85
    }
86
87
    /**
88
     * Write the value to the writer for the type
89
     *
90
     * @param array|null $value
91
     * @param WriterContext $context
92
     * @return array|null
93
     */
94
    public function write($value, WriterContext $context): ?array
95
    {
96
        if ($value === null) {
97
            return null;
98
        }
99
100
        $serializeNull = $context->serializeNull();
101
        $result = [];
102
        $arrayIsObject = is_string(key($value));
103
104
        if ($arrayIsObject !== $this->stringKeys) {
105
            throw new JsonSyntaxException(
106
                sprintf(
107
                    'Expected %s, but found %s for key',
108
                    $this->stringKeys ? 'string' : 'integer',
109
                    $arrayIsObject ? 'string' : 'integer'
110
                )
111
            );
112
        }
113
114
        foreach ($value as $key => $item) {
115
            if ($item === null && !$serializeNull) {
116
                continue;
117
            }
118
119
            $itemValue = $this->valueTypeAdapter->write($item, $context);
120
            if ($itemValue === null && !$serializeNull) {
121
                continue;
122
            }
123
124
            if ($this->stringKeys) {
125
                $result[(string)$key] = $itemValue;
126
            } else {
127
                $result[] = $itemValue;
128
            }
129
        }
130
131
        return $result;
132
    }
133
134
    /**
135
     * Return true if object can be written to disk
136
     *
137
     * @return bool
138
     */
139
    public function canCache(): bool
140
    {
141
        return $this->valueTypeAdapter->canCache();
142
    }
143
}
144