Passed
Push — master ( e6bc2a...a7212f )
by Kirill
04:45
created

SchemaBuilder::getFieldName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 0
cts 8
cp 0
rs 9.9332
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 6
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\Builder\Definition;
11
12
use Railt\Parser\Ast\RuleInterface;
13
use Railt\Reflection\Contracts\Definition;
14
use Railt\Reflection\Definition\SchemaDefinition;
15
use Railt\Reflection\Type;
16
use Railt\SDL\Builder\Utils;
17
use Railt\SDL\Exception\InternalErrorException;
18
use Railt\SDL\Exception\TypeException;
19
20
/**
21
 * Class SchemaBuilder
22
 */
23
class SchemaBuilder extends TypeDefinitionBuilder
24
{
25
    /**
26
     * @return Definition
27
     */
28
    public function build(): Definition
29
    {
30
        /** @var SchemaDefinition $schema */
31
        $schema = $this->bind(new SchemaDefinition($this->document, $this->findName()));
32
33
        foreach ($this->ast as $child) {
34
            $this->async(function () use ($child, $schema): void {
35
                $this->buildField($child, $schema);
36
            });
37
        }
38
39
        return $schema;
40
    }
41
42
    /**
43
     * @param RuleInterface $rule
44
     * @param SchemaDefinition $definition
45
     * @throws \Railt\Io\Exception\ExternalFileException
46
     * @throws InternalErrorException
47
     */
48
    private function buildField(RuleInterface $rule, SchemaDefinition $definition): void
49
    {
50
        $name = $this->getFieldName($rule);
51
        $type = $this->getFieldType($rule, $definition, $name);
52
53
        switch ($name) {
54
            case 'query':
55
                $definition->withQuery($type);
56
                break;
57
58
            case 'mutation':
59
                $definition->withMutation($type);
60
                break;
61
62
            case 'subscription':
63
                $definition->withSubscription($type);
64
                break;
65
        }
66
    }
67
68
    /**
69
     * @param RuleInterface $rule
70
     * @return string
71
     * @throws InternalErrorException
72
     */
73
    private function getFieldName(RuleInterface $rule): string
74
    {
75
        $type = Utils::leaf($rule, 'SchemaFieldType');
76
77
        if ($type === null) {
78
            throw new InternalErrorException('Rule SchemaFieldType not found');
79
        }
80
81
        return $type;
82
    }
83
84
    /**
85
     * @param RuleInterface $rule
86
     * @param SchemaDefinition $definition
87
     * @param string $field
88
     * @return Definition
89
     * @throws InternalErrorException
90
     * @throws TypeException
91
     * @throws \Railt\SDL\Exception\TypeNotFoundException
92
     */
93
    private function getFieldType(RuleInterface $rule, SchemaDefinition $definition, string $field): Definition
94
    {
95
        if (($type = Utils::rule($rule, 'Type')) === null) {
96
            throw new InternalErrorException('Rule Type not found');
97
        }
98
99
        if (($name = Utils::findName($type)) === null) {
100
            $error = \sprintf('Schema %s field type can not be List or NonNull', $field);
101
102
            $exception = new TypeException($error);
103
            $exception->throwsIn($this->file, $type->getOffset());
104
105
            throw $exception;
106
        }
107
108
        $result = $this->load($name, $definition, $type->getOffset());
109
110
        if (! Type::of($result::getType())->is(Type::OBJECT)) {
111
            $error = 'Schema %s field type should be an %s, but %s given';
112
            $error = \sprintf($error, $field, Type::OBJECT, $result);
113
114
            $exception = new TypeException($error);
115
            $exception->throwsIn($this->file, $type->getOffset());
116
117
            throw $exception;
118
        }
119
120
        return $result;
121
    }
122
}
123