Passed
Push — master ( 81d6c9...698aea )
by Martijn
02:30
created

Integer::__construct()   A

Complexity

Conditions 6
Paths 3

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 10
nc 3
nop 3
dl 0
loc 17
ccs 11
cts 11
cp 1
crap 6
rs 9.2222
c 0
b 0
f 0
1
<?php
2
3
namespace Vanderlee\Comprehend\Parser\Terminal;
4
5
use Exception;
6
use Vanderlee\Comprehend\Core\Context;
7
use Vanderlee\Comprehend\Parser\Parser;
8
use Vanderlee\Comprehend\Match\Failure;
9
use Vanderlee\Comprehend\Match\Success;
10
11
/**
12
 * Matches an integer within the specified range
13
 *
14
 * @author Martijn
15
 */
16
class Integer extends Parser
17
{
18
    use CaseSensitiveTrait;
19
20
    /**
21
     * List of digits to use for the different bases (up to 36)
22
     * @var string
23
     */
24
    private static $set = '0123456789abcdefghijklmnopqrstuvwxyz';
25
26
    /**
27
     * @var int|null
28
     */
29
    private $minimum;
30
31
    /**
32
     * @var int|null
33
     */
34
    private $maximum;
35
36
    /**
37
     * @var int
38
     */
39
    private $base;
40
41
    /**
42
     * @param int|null $minimum
43
     * @param int|null $maximum
44
     * @param int $base
45
     * @throws Exception
46
     */
47 8
    public function __construct($minimum = 0, $maximum = null, $base = 10)
48
    {
49 8
        if ($minimum !== null
50 8
            && $maximum !== null
51 8
            && $minimum > $maximum) {
52
53 1
            throw new \Exception('Maximum must be greater than minimum');
54
        }
55
56 7
        $this->setMinimum($minimum);
57 6
        $this->setMaximum($maximum);
58
59 5
        $this->base = intval($base);
60 5
        if ($base < 2
61 5
            || $base > strlen(self::$set)) {
62
63 2
            throw new \Exception('Unsupported base');
64
        }
65 3
    }
66
67
    /**
68
     * @param int $minimum
69
     * @throws Exception
70
     */
71 7
    private function setMinimum($minimum)
72
    {
73 7
        if ($minimum !== null
74 7
            && !is_int($minimum)) {
0 ignored issues
show
introduced by
The condition is_int($minimum) is always true.
Loading history...
75
76 1
            throw new Exception('Minimum must be integer or `null`');
77
        }
78
79 6
        $this->minimum = $minimum;
80 6
    }
81
82
    /**
83
     * @param int $maximum
84
     * @throws Exception
85
     */
86 6
    private function setMaximum($maximum)
87
    {
88 6
        if ($maximum !== null
89 6
            && !is_int($maximum)) {
0 ignored issues
show
introduced by
The condition is_int($maximum) is always true.
Loading history...
90
91 1
            throw new Exception('Maximum must be integer or `null`');
92
        }
93
94 5
        $this->maximum = $maximum;
95 5
    }
96
97
    /**
98
     * @param string $input
99
     * @param int $offset
100
     * @param Context $context
101
     * @return Failure|Success
102
     */
103 54
    protected function parse(&$input, $offset, Context $context)
104
    {
105 54
        $this->pushCaseSensitivityToContext($context);
106
107
        // Build pattern
108 54
        $set0    = substr(self::$set, 0, $this->base);
109 54
        $set1    = substr(self::$set, 1, $this->base - 1);
110 54
        $pattern = '/(?:0|-?[' . $set1 . '][' . $set0 . ']*)/A' . ($context->isCaseSensitive()
111 51
                ? ''
112 54
                : 'i');
113
114 54
        $this->popCaseSensitivityFromContext($context);
115
116 54
        if (preg_match($pattern, $input, $match, 0, $offset) === 1) {
117
            do {
118 51
                $integer = intval($match[0], $this->base);
119 51
                if (($this->minimum === null || $integer >= $this->minimum)
120 51
                    && ($this->maximum === null || $integer <= $this->maximum)
121 51
                    && $match[0] !== '-') {
122 40
                    return $this->success($input, $offset, mb_strlen($match[0]));
123
                }
124
125 18
                $match[0] = substr($match[0], 0, -1); // strip off last char
126 18
            } while ($match[0] !== '');
127
        }
128
129 14
        return $this->failure($input, $offset);
130
    }
131
132
    /**
133
     * @return string
134
     */
135 54
    public function __toString()
136
    {
137 54
        return ($this->minimum === null
138 7
                ? '<-INF'
139 54
                : ('[' . $this->minimum)) . ',' . ($this->maximum === null
140 14
                ? 'INF>'
141 54
                : ($this->maximum . ']'));
142
    }
143
144
}
145