Completed
Push — master ( c45521...844759 )
by stéphane
08:22
created

NodeFactory::onSpecial()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 2
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Dallgoot\Yaml;
4
5
/**
6
 * TODO
7
 *
8
 * @author  Stéphane Rebai <[email protected]>
9
 * @license Apache 2.0
10
 * @link    TODO : url to specific online doc
11
 */
12
final class NodeFactory
13
{
14
    private const JSON_OPTIONS = \JSON_PARTIAL_OUTPUT_ON_ERROR|\JSON_UNESCAPED_SLASHES;
15
16
    final public static function get($nodeString = null, $line = 0):Node
17
    {
18
        $nodeTrimmed = ltrim($nodeString);
19
        if ($nodeTrimmed === '') {
20
            return new NodeBlank($nodeString, $line);
21
        } elseif (substr($nodeTrimmed, 0, 3) === '...') {
22
            return new NodeDocEnd($nodeString, $line);
23
        } elseif (preg_match(Regex::KEY, $nodeTrimmed, $matches)) {
24
            return new NodeKey($nodeString, $line, $matches);
25
        } else {
26
            $first = $nodeTrimmed[0];
27
            $actions = ["-"   => 'onHyphen',
28
                        '>|'  => 'onLiteral',
29
                        '"\'' => 'onQuoted',
30
                        "#%"  => 'onSpecial',
31
                        "{["  => 'onCompact',
32
                        ":?"  => 'onSetElement',
33
                        '*&!' => 'onNodeAction'
34
                    ];
35
            foreach ($actions as $stringRef => $methodName) {
36
                if (is_int(strrpos($stringRef, $first))) {
37
                    return self::$methodName($nodeString, $line);
38
                }
39
            }
40
        }
41
        return new NodeScalar($nodeString, $line);
42
    }
43
44
    /**
45
     * Return the correct Node Object between NodeComment OR NodeDirective
46
     *
47
     * @param      string   $nodeString  The node string
48
     * @param      integer  $line         The line
49
     *
50
     * @return     Node
51
     */
52
    final private static function onSpecial(string $nodeString, int $line):Node
53
    {
54
        return $nodeString[0] === "#" ? new NodeComment($nodeString, $line) : new NodeDirective($nodeString, $line);
55
    }
56
57
    /**
58
     * Set $node type and value when $nodevalue starts with a quote (simple or double)
59
     *
60
     * @param string $nodeString The node value
61
     * @param int    $line       The line
62
     *
63
     * @return     Node
64
     */
65
    final private static function onQuoted(string $nodeString, int $line):Node
66
    {
67
        $trimmed = trim($nodeString);
68
        return Regex::isProperlyQuoted($trimmed) ? new NodeQuoted($trimmed, $line) : new NodeScalar($trimmed, $line);
69
    }
70
71
    /**
72
     * Set $node type and value when NodeValue starts with a Set characters "?:"
73
     *
74
     * @param string $nodeString The node value
75
     * @param int    $line       The line
76
     *
77
     * @return     Node
78
     */
79
    final private static function onSetElement(string $nodeString, int $line):Node
80
    {
81
        return $nodeString[0] === '?' ? new NodeSetKey($nodeString, $line) : new NodeSetValue($nodeString, $line);
82
    }
83
84
    /**
85
     * Determines the Node type and value when a compact object/array syntax is found
86
     *
87
     * @param string $nodeString The value assumed to start with { or [ or characters
88
     * @param int    $line       The line
89
     *
90
     * @return     Node
91
     */
92
    final private static function onCompact(string $nodeString, int $line):Node
93
    {
94
        $json = json_decode($nodeString, false, 512, self::JSON_OPTIONS);
95
        if (json_last_error() === \JSON_ERROR_NONE)       return new NodeJSON($nodeString, $line, $json);
96
        elseif (preg_match(Regex::MAPPING, $nodeString))  return new NodeCompactMapping($nodeString, $line);
97
        elseif (preg_match(Regex::SEQUENCE, $nodeString)) return new NodeCompactSequence($nodeString, $line);
98
        else {
99
            return new NodePartial($nodeString, $line);
100
        }
101
    }
102
103
    /**
104
     * Determines Node type and value when an hyphen "-" is found
105
     *
106
     * @param string $nodeString The node string value
107
     * @param int    $line       The line
108
     *
109
     * @return     Node
110
     */
111
    final private static function onHyphen(string $nodeString, int $line):Node
112
    {
113
        if (substr($nodeString, 0, 3) === '---')       return new NodeDocStart($nodeString, $line);
114
        elseif (preg_match(Regex::ITEM, $nodeString))  return new NodeItem($nodeString, $line);
115
        else {
116
            return new NodeScalar($nodeString, $line);
117
        }
118
    }
119
120
    /**
121
     * Sets Node type and value according to $nodeString when one of these characters is found : !,&,*
122
     *
123
     * @param string $nodeString The node value
124
     * @param int    $line       The line
125
     *
126
     */
127
    final private static function onNodeAction(string $nodeString, int $line):Node
128
    {
129
        if ($nodeString[0] === '!')     return new NodeTag($nodeString, $line);
130
        elseif ($nodeString[0] === '&') return new NodeRefDef($nodeString, $line);
131
        elseif ($nodeString[0] === '*') return new NodeRefCall($nodeString, $line);
132
        else {
133
            throw new \ParseError("Not a action node !! $nodeString[0]");
134
        }
135
    }
136
137
138
    final private static function onLiteral(string $nodeString, int $line):Node
139
    {
140
        if ($nodeString[0] === '>')      return new NodeLitFolded($nodeString, $line);
141
        elseif ($nodeString[0] === '|')  return new NodeLit($nodeString, $line);
142
        else {
143
            throw new \ParseError("Not a literal node !! $nodeString[0]");
144
        }
145
    }
146
147
}