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

ArrayTypeAdapter   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 21
eloc 42
c 0
b 0
f 0
dl 0
loc 104
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A canCache() 0 3 1
A __sleep() 0 3 1
B write() 0 35 11
B read() 0 29 8
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
use Tebru\PhpType\TypeToken;
16
17
/**
18
 * Class ArrayTypeAdapter
19
 *
20
 * @author Nate Brunette <[email protected]>
21
 */
22
class ArrayTypeAdapter extends TypeAdapter
23
{
24
    /**
25
     * A TypeAdapter cache keyed by raw type
26
     *
27
     * @var TypeAdapter[]
28
     */
29
    protected $adapters = [];
30
31
    /**
32
     * Read the next value, convert it to its type and return it
33
     *
34
     * @param array|null $value
35
     * @param ReaderContext $context
36
     * @return array|null
37
     */
38
    public function read($value, ReaderContext $context): ?array
39
    {
40
        if ($value === null) {
41
            return null;
42
        }
43
44
        if (!is_array($value)) {
45
            throw new JsonSyntaxException(sprintf('Could not parse json, expected array or object but found "%s"', gettype($value)));
46
        }
47
48
        $result = [];
49
50
        $arrayIsObject = is_string(key($value));
51
        $enableScalarAdapters = $context->enableScalarAdapters();
52
        $typeAdapterProvider = $context->getTypeAdapterProvider();
53
54
        foreach ($value as $key => $item) {
55
            if (!$enableScalarAdapters && ($item === null || is_scalar($item))) {
56
                $itemValue = $item;
57
            } else {
58
                $type = TypeToken::createFromVariable($item);
59
                $adapter = $this->adapters[$type->rawType] ?? $this->adapters[$type->rawType] = $typeAdapterProvider->getAdapter($type);
60
                $itemValue = $adapter->read($item, $context);
61
            }
62
63
            $result[$arrayIsObject ? (string)$key : (int)$key] = $itemValue;
64
        }
65
66
        return $result;
67
    }
68
69
    /**
70
     * Write the value to the writer for the type
71
     *
72
     * @param array|null $value
73
     * @param WriterContext $context
74
     * @return array|null
75
     */
76
    public function write($value, WriterContext $context): ?array
77
    {
78
        if ($value === null) {
79
            return null;
80
        }
81
82
        $arrayIsObject = is_string(key($value));
83
        $enableScalarAdapters = $context->enableScalarAdapters();
84
        $serializeNull = $context->serializeNull();
85
        $typeAdapterProvider = $context->getTypeAdapterProvider();
86
        $result = [];
87
88
        foreach ($value as $key => $item) {
89
            if ($item === null && !$serializeNull) {
90
                continue;
91
            }
92
93
            if (!$enableScalarAdapters && is_scalar($item)) {
94
                $result[$arrayIsObject ? (string)$key : (int)$key] = $item;
95
                continue;
96
            }
97
98
            $itemValue = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $itemValue is dead and can be removed.
Loading history...
99
            $type = TypeToken::createFromVariable($item);
100
            $adapter = $this->adapters[$type->rawType] ?? $this->adapters[$type->rawType] = $typeAdapterProvider->getAdapter($type);
101
            $itemValue = $adapter->write($item, $context);
102
103
            if ($itemValue === null && !$serializeNull) {
104
                continue;
105
            }
106
107
            $result[$arrayIsObject ? (string)$key : (int)$key] = $itemValue;
108
        }
109
110
        return $result;
111
    }
112
113
    /**
114
     * Return true if object can be written to disk
115
     *
116
     * @return bool
117
     */
118
    public function canCache(): bool
119
    {
120
        return true;
121
    }
122
123
    public function __sleep()
124
    {
125
        return [];
126
    }
127
}
128