Completed
Push — master ( dee7d0...3607c7 )
by Chris
02:30
created

NodeFactory::createNodeFromValue()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 6.3183

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 5
cts 8
cp 0.625
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 10
nc 4
nop 3
crap 6.3183
1
<?php declare(strict_types=1);
2
3
namespace DaveRandom\Jom;
4
5
use DaveRandom\Jom\Exceptions\Exception;
6
use DaveRandom\Jom\Exceptions\InvalidNodeValueException;
7
8
abstract class NodeFactory
9
{
10
    private const SCALAR_VALUE_NODE_CLASSES = [
11
        'boolean' => BooleanNode::class,
12
        'integer' => NumberNode::class,
13
        'double' => NumberNode::class,
14
        'string' => StringNode::class,
15
    ];
16
17
    /**
18
     * @throws Exception
19
     * @throws InvalidNodeValueException
20
     */
21 94
    final protected function createArrayNodeFromPackedArray(array $values, ?Document $doc, int $flags): ArrayNode
22
    {
23 94
        $node = new ArrayNode([], $doc);
24
25 94
        foreach ($values as $value) {
26 89
            if (null !== $valueNode = $this->createNodeFromValue($value, $doc, $flags)) {
27 89
                $node->push($valueNode);
28
            }
29
        }
30
31 94
        return $node;
32
    }
33
34
    /**
35
     * @throws Exception
36
     * @throws InvalidNodeValueException
37
     */
38 64
    final protected function createObjectNodeFromPropertyMap($properties, ?Document $doc, int $flags): ObjectNode
39
    {
40 64
        $node = new ObjectNode([], $doc);
41
42 64
        foreach ($properties as $name => $value) {
43 64
            if (null !== $valueNode = $this->createNodeFromValue($value, $doc, $flags)) {
44 64
                $node->setProperty($name, $valueNode);
45
            }
46
        }
47
48 64
        return $node;
49
    }
50
51 101
    final protected function createScalarOrNullNodeFromValue($value, ?Document $doc): ?Node
52
    {
53 101
        if ($value === null) {
54 35
            return new NullNode($doc);
55
        }
56
57 94
        $className = self::SCALAR_VALUE_NODE_CLASSES[\gettype($value)] ?? null;
58
59 94
        if ($className !== null) {
60 64
            return new $className($value, $doc);
61
        }
62
63 94
        return null;
64
    }
65
66
    /**
67
     * @throws Exception
68
     * @throws InvalidNodeValueException
69
     */
70
    abstract protected function createVectorNodeFromValue($value, ?Document $doc, int $flags): ?Node;
71
72
    /**
73
     * @throws InvalidNodeValueException
74
     */
75 101
    final public function createNodeFromValue($value, ?Document $doc, int $flags): ?Node
76
    {
77
        try {
78 101
            $node = $this->createScalarOrNullNodeFromValue($value, $doc)
79 101
                ?? $this->createVectorNodeFromValue($value, $doc, $flags);
80
81 101
            if ($node !== null || ($flags & Node::IGNORE_INVALID_VALUES)) {
82 101
                return $node;
83
            }
84
        } catch (InvalidNodeValueException $e) {
85
            throw $e;
86
        //@codeCoverageIgnoreStart
87
        } catch (\Exception $e) {
88
            throw unexpected($e);
89
        }
90
        //@codeCoverageIgnoreEnd
91
92
        throw new InvalidNodeValueException("Failed to create node from value of type '" . \gettype($value) . "'");
93
    }
94
}
95