Passed
Push — master ( 254c29...f2eb24 )
by Yo
03:16
created

DocTypeHelper   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 21
eloc 44
dl 0
loc 92
ccs 46
cts 46
cp 1
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B normalizeType() 0 21 9
A guess() 0 5 1
B getDocFromTypeConstraintOrPayloadDocIfExist() 0 29 10
1
<?php
2
namespace Yoanm\JsonRpcParamsSymfonyConstraintDoc\App\Helper;
3
4
use Symfony\Component\Validator\Constraint;
5
use Symfony\Component\Validator\Constraints as Assert;
6
use Yoanm\JsonRpcServerDoc\Domain\Model\Type\ArrayDoc;
7
use Yoanm\JsonRpcServerDoc\Domain\Model\Type\BooleanDoc;
8
use Yoanm\JsonRpcServerDoc\Domain\Model\Type\FloatDoc;
9
use Yoanm\JsonRpcServerDoc\Domain\Model\Type\IntegerDoc;
10
use Yoanm\JsonRpcServerDoc\Domain\Model\Type\NumberDoc;
11
use Yoanm\JsonRpcServerDoc\Domain\Model\Type\ObjectDoc;
12
use Yoanm\JsonRpcServerDoc\Domain\Model\Type\ScalarDoc;
13
use Yoanm\JsonRpcServerDoc\Domain\Model\Type\StringDoc;
14
use Yoanm\JsonRpcServerDoc\Domain\Model\Type\TypeDoc;
15
16
/**
17
 * Class DocTypeHelper
18
 */
19
class DocTypeHelper
20
{
21
    /** @var ConstraintPayloadDocHelper */
22
    private $constraintPayloadDocHelper;
23
    /** @var TypeGuesser */
24
    private $typeGuesser;
25
26
    /**
27
     * @param ConstraintPayloadDocHelper $constraintPayloadDocHelper
28
     * @param TypeGuesser                $typeGuesser
29
     */
30 25
    public function __construct(ConstraintPayloadDocHelper $constraintPayloadDocHelper, TypeGuesser $typeGuesser)
31
    {
32 25
        $this->constraintPayloadDocHelper = $constraintPayloadDocHelper;
33 25
        $this->typeGuesser = $typeGuesser;
34 25
    }
35
36
    /**
37
     * @param Constraint[] $constraintList
38
     *
39
     * @return TypeDoc
40
     */
41 25
    public function guess(array $constraintList) : TypeDoc
42
    {
43 25
        return $this->getDocFromTypeConstraintOrPayloadDocIfExist($constraintList)
44 3
            ?? $this->typeGuesser->guessTypeFromConstraintList($constraintList)
45 25
            ?? new TypeDoc()
46
        ;
47
    }
48
49
    /**
50
     * @param Constraint[] $constraintList
51
     *
52
     * @return TypeDoc|null
53
     */
54 25
    protected function getDocFromTypeConstraintOrPayloadDocIfExist(array $constraintList) : ?TypeDoc
55
    {
56 25
        $doc = null;
57
        // Check if a Type constraint exist or if a constraint have a type documentation
58 25
        foreach ($constraintList as $constraint) {
59 24
            if (null !== ($typeFromPayload = $this->constraintPayloadDocHelper->getTypeIfExist($constraint))) {
60 1
                $doc = $this->normalizeType($typeFromPayload);
61 23
            } elseif ($constraint instanceof Assert\Type) {
62 18
                $doc = $this->normalizeType(strtolower($constraint->type));
63 9
            } elseif ($constraint instanceof Assert\Existence && count($constraint->constraints) > 0) {
64 2
                $doc = $this->guess($constraint->constraints);
65 7
            } elseif ($constraint instanceof Assert\IdenticalTo) {
66
                // Strict comparison so value define the type
67 4
                $doc = $this->normalizeType(gettype($constraint->value));
68 3
            } elseif ($constraint instanceof Assert\Callback) {
69 2
                $callbackResult = call_user_func($constraint->callback);
70 2
                $doc = $this->guess(
71 2
                    is_array($callbackResult)
72 1
                        ? $callbackResult
73 2
                        : [$callbackResult]
74
                );
75
            }
76
77 24
            if (null !== $doc) {
78 24
                break;
79
            }
80
        }
81
82 25
        return $doc;
83
    }
84
85
    /**
86
     * @param string $type
87
     *
88
     * @return TypeDoc|null
89
     */
90 23
    private function normalizeType(string $type) : ?TypeDoc
91
    {
92 23
        if ('scalar' === $type) {
93 1
            return new ScalarDoc();
94 22
        } elseif ('string' === $type) {
95 4
            return new StringDoc();
96 18
        } elseif (in_array($type, ['bool', 'boolean'])) {
97 3
            return new BooleanDoc();
98 15
        } elseif (in_array($type, ['int', 'integer'])) {
99 3
            return new IntegerDoc();
100 12
        } elseif (in_array($type, ['float', 'long', 'double', 'real'])) {
101 7
            return new FloatDoc();
102 5
        } elseif ('numeric' === $type) {
103 1
            return new NumberDoc();
104 4
        } elseif ('array' === $type) {
105 2
            return new ArrayDoc();
106 2
        } elseif ('object' === $type) {
107 1
            return new ObjectDoc();
108
        }
109
110 1
        return null;
111
    }
112
}
113