Encoders   A
last analyzed

Complexity

Total Complexity 35

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 81
dl 0
loc 153
rs 9.6
c 0
b 0
f 0
wmc 35

7 Methods

Rating   Name   Duplication   Size   Complexity  
A encodeObject() 0 15 6
A encode() 0 8 1
A isUniformArray() 0 21 6
A encodeArray() 0 15 3
A encodeTabularArray() 0 18 3
B encodeValue() 0 15 7
B encodeIndexedArray() 0 44 9
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Squareetlabs\LaravelToon\Toon;
6
7
class Encoders
8
{
9
    public static function encode(mixed $data, EncodeOptions $options = new EncodeOptions()): string
10
    {
11
        $normalized = Normalize::normalize($data);
12
        $writer = new LineWriter($options->indent);
13
14
        self::encodeValue($normalized, $writer, $options);
15
16
        return $writer->getContent();
17
    }
18
19
    private static function encodeValue(mixed $value, LineWriter $writer, EncodeOptions $options): void
20
    {
21
        if (null === $value || is_bool($value) || is_int($value) || is_float($value) || is_string($value)) {
22
            $writer->line(Primitives::encode($value));
23
24
            return;
25
        }
26
27
        if (is_array($value)) {
28
            self::encodeArray($value, $writer, $options);
29
30
            return;
31
        }
32
33
        $writer->line();
34
    }
35
36
    private static function encodeArray(array $array, LineWriter $writer, EncodeOptions $options): void
37
    {
38
        if (empty($array)) {
39
            $writer->line('[]');
40
41
            return;
42
        }
43
44
        // Check if it's associative or indexed
45
        $isAssociative = !array_is_list($array);
0 ignored issues
show
Bug introduced by
The function array_is_list was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

45
        $isAssociative = !/** @scrutinizer ignore-call */ array_is_list($array);
Loading history...
46
47
        if ($isAssociative) {
48
            self::encodeObject($array, $writer, $options);
49
        } else {
50
            self::encodeIndexedArray($array, $writer, $options);
51
        }
52
    }
53
54
    private static function encodeObject(array $object, LineWriter $writer, EncodeOptions $options): void
55
    {
56
        foreach ($object as $key => $value) {
57
            $keyStr = is_int($key) ? (string)$key : $key;
58
59
            if (is_array($value) && !empty($value)) {
60
                $writer->line($keyStr.Constants::OBJECT_MARKER);
61
                $writer->indent();
62
                self::encodeArray($value, $writer, $options);
63
                $writer->dedent();
64
            } elseif (is_array($value)) {
65
                $writer->line($keyStr.Constants::OBJECT_MARKER.' []');
66
            } else {
67
                $encoded = Primitives::encode($value);
68
                $writer->line($keyStr.Constants::OBJECT_MARKER.' '.$encoded);
69
            }
70
        }
71
    }
72
73
    private static function encodeIndexedArray(array $array, LineWriter $writer, EncodeOptions $options): void
74
    {
75
        $count = count($array);
76
        $allPrimitives = true;
77
        $allObjects = true;
78
79
        foreach ($array as $item) {
80
            if (is_array($item)) {
81
                $allPrimitives = false;
82
            } else {
83
                $allObjects = false;
84
            }
85
        }
86
87
        // All primitives - inline format
88
        if ($allPrimitives) {
89
            $encoded = array_map(fn ($item) => Primitives::encode($item), $array);
90
            $content = implode($options->delimiter, $encoded);
91
            $writer->line($count.Constants::ARRAY_MARKER_END.Constants::ARRAY_HEADER_DELIMITER.' '.$content);
92
93
            return;
94
        }
95
96
        // Check if uniform objects
97
        if ($allObjects && count($array) >= $options->minRowsToTabular) {
98
            $isUniform = self::isUniformArray($array);
99
            if ($isUniform) {
100
                self::encodeTabularArray($array, $writer, $options);
101
102
                return;
103
            }
104
        }
105
106
        // List format with hyphens
107
        $writer->line($count.Constants::ARRAY_MARKER_END.Constants::OBJECT_MARKER);
108
        $writer->indent();
109
        foreach ($array as $item) {
110
            if (is_array($item)) {
111
                self::encodeArray($item, $writer, $options);
112
            } else {
113
                $writer->line(Primitives::encode($item));
114
            }
115
        }
116
        $writer->dedent();
117
    }
118
119
    private static function isUniformArray(array $array): bool
120
    {
121
        if (empty($array)) {
122
            return false;
123
        }
124
125
        $firstKeys = null;
126
        foreach ($array as $item) {
127
            if (!is_array($item)) {
128
                return false;
129
            }
130
131
            $keys = array_keys($item);
132
            if (null === $firstKeys) {
133
                $firstKeys = $keys;
134
            } elseif ($keys !== $firstKeys) {
135
                return false;
136
            }
137
        }
138
139
        return true;
140
    }
141
142
    private static function encodeTabularArray(array $array, LineWriter $writer, EncodeOptions $options): void
143
    {
144
        $count = count($array);
145
        $keys = array_keys(reset($array) ?? []);
146
        $keysStr = implode($options->delimiter, $keys);
147
148
        $writer->line($count.Constants::ARRAY_MARKER_END.Constants::ARRAY_FIELD_WRAPPER_START.$keysStr.Constants::ARRAY_FIELD_WRAPPER_END.Constants::OBJECT_MARKER);
149
        $writer->indent();
150
151
        foreach ($array as $row) {
152
            $values = [];
153
            foreach ($keys as $key) {
154
                $values[] = Primitives::encode($row[$key] ?? null);
155
            }
156
            $writer->line(implode($options->delimiter, $values));
157
        }
158
159
        $writer->dedent();
160
    }
161
}
162
163