Completed
Push — master ( 5ac91e...39483e )
by Kirill
38:30
created

Support   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 149
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 82%

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 8
dl 0
loc 149
ccs 41
cts 50
cp 0.82
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
B typeToString() 0 22 4
B typeIndicatorToString() 0 22 5
A valueWithType() 0 4 1
C valueToScalar() 0 35 8
A valueToString() 0 14 2
1
<?php
2
/**
3
 * This file is part of Railt package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace Railt\SDL;
11
12
use Railt\SDL\Contracts\Behavior\AllowsTypeIndication;
13
use Railt\SDL\Contracts\Definitions\Definition;
14
use Railt\SDL\Contracts\Definitions\TypeDefinition;
15
use Railt\SDL\Contracts\Dependent\ArgumentDefinition;
16
use Railt\SDL\Contracts\Dependent\FieldDefinition;
17
18
/**
19
 * Trait Support
20
 */
21
trait Support
22
{
23
    /**
24
     * @var string
25
     */
26
    private static $typeDefinition = '%s<%s>';
27
28
    /**
29
     * @var string
30
     */
31
    private static $fieldDefinition = '{%s: %s}';
32
33
    /**
34
     * @var string
35
     */
36
    private static $argumentDefinition = '(%s: %s)';
37
38
    /**
39
     * @var string
40
     */
41
    private static $syntaxList = '[%s]';
42
43
    /**
44
     * @var string
45
     */
46
    private static $syntaxNonNull = '%s!';
47
48
    /**
49
     * @param AllowsTypeIndication|Definition $type
50
     * @return string
51
     */
52 3645
    protected function typeToString(Definition $type): string
53
    {
54 3645
        if ($type instanceof ArgumentDefinition) {
55 2535
            return \vsprintf(self::$argumentDefinition, [
56 2535
                $type->getName(),
57 2535
                $this->typeIndicatorToString($type),
58
            ]);
59
        }
60
61 1434
        if ($type instanceof FieldDefinition) {
62 395
            return \vsprintf(self::$fieldDefinition, [
63 395
                $type->getName(),
64 395
                $this->typeIndicatorToString($type),
65
            ]);
66
        }
67
68 1402
        if ($type instanceof TypeDefinition) {
69 1402
            return \sprintf(self::$typeDefinition, $type->getTypeName(), $type->getName());
70
        }
71
72
        return $type->getName();
73
    }
74
75
    /**
76
     * @param AllowsTypeIndication $type
77
     * @return string
78
     */
79 2930
    protected function typeIndicatorToString(AllowsTypeIndication $type): string
80
    {
81
        try {
82 2930
            $result = $type->getTypeDefinition()->getName();
83
84 2930
            if ($type->isList()) {
85 1239
                if ($type->isListOfNonNulls()) {
86 1223
                    $result = \sprintf(self::$syntaxNonNull, $result);
87
                }
88
89 1239
                $result = \sprintf(self::$syntaxList, $result);
90
            }
91
92 2930
            if ($type->isNonNull()) {
93 337
                $result = \sprintf(self::$syntaxNonNull, $result);
94
            }
95
96 2930
            return $result;
97
        } catch (\Throwable $e) {
98
            return '?';
99
        }
100
    }
101
102
    /**
103
     * @param $value
104
     * @return string
105
     */
106
    protected function valueWithType($value): string
107
    {
108
        return \mb_strtolower(\gettype($value)) . ' ' . $this->valueToString($value);
109
    }
110
111
    /**
112
     * @param mixed $value
113
     * @return mixed
114
     */
115 1946
    protected function valueToScalar($value)
116
    {
117 1946
        if (\is_scalar($value)) {
118 829
            return $value;
119
        }
120
121 1910
        if (\is_iterable($value)) {
122 1910
            $result = [];
123
124
            /** @var iterable $value */
125 1910
            foreach ($value as $key => $sub) {
126 1201
                $result[$key] = $this->valueToScalar($sub);
127
            }
128
129 1910
            return $result;
130
        }
131
132 1201
        if ($value instanceof Definition) {
133
            return $this->typeToString($value);
134
        }
135
136 1201
        if ($value instanceof \Illuminate\Contracts\Support\Arrayable) {
137
            return $this->valueToScalar($value->toArray());
138
        }
139
140 1201
        if ($value instanceof \Illuminate\Contracts\Support\Jsonable) {
141
            return $this->valueToScalar(\json_decode($value->toJson(), true));
142
        }
143
144 1201
        if ($value instanceof \JsonSerializable) {
145
            return $this->valueToScalar(\json_encode($value->jsonSerialize(), true));
146
        }
147
148 1201
        return \ucfirst(\strtolower(\gettype($value)));
149
    }
150
151
    /**
152
     * @param mixed|iterable|null $value
153
     * @return string
154
     */
155 1946
    protected function valueToString($value): string
156
    {
157 1946
        $result = $this->valueToScalar($value);
158
159 1946
        if (\is_array($result)) {
160 1910
            $result = \json_encode($result);
161 1910
            $result = \preg_replace('/"([_A-Za-z][_0-9A-Za-z]*)":/u', '$1: ', $result);
162 1910
            $result = \preg_replace('/:\s+(.*?),/u', ': $1, ', $result);
163
164 1910
            return $result;
165
        }
166
167 36
        return (string)$result;
168
    }
169
}
170