Passed
Push — master ( 33b535...ab5fff )
by Nelson
02:44
created

IntString::parse()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 39
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5.0061

Importance

Changes 0
Metric Value
cc 5
eloc 22
nc 5
nop 1
dl 0
loc 39
rs 9.2568
c 0
b 0
f 0
ccs 15
cts 16
cp 0.9375
crap 5.0061
1
<?php
2
/**
3
 * PHP: Nelson Martell Library file
4
 *
5
 * Copyright © 2015-2019 Nelson Martell (http://nelson6e65.github.io)
6
 *
7
 * Licensed under The MIT License (MIT)
8
 * For full copyright and license information, please see the LICENSE
9
 * Redistributions of files must retain the above copyright notice.
10
 *
11
 * @copyright 2015-2019 Nelson Martell
12
 * @link      http://nelson6e65.github.io/php_nml/
13
 * @since     0.1.1
14
 * @license   http://www.opensource.org/licenses/mit-license.php The MIT License (MIT)
15
 * */
16
17
namespace NelsonMartell;
18
19
use NelsonMartell\Extensions\Text;
20
use InvalidArgumentException;
21
22
/**
23
 * Representa un elemento mixto, compuesto por un entero y una cadena unidos
24
 * (en ese orden).
25
 * El método IntString::toString obtiene esa cadena compuesta.
26
 *
27
 * @author Nelson Martell <[email protected]>
28
 * @since 0.1.1
29
 *
30
 * @property-read int    $intValue    Gets the integer part.
31
 * @property-read string $stringValue Gets the string part.
32
 * */
33
class IntString extends StrictObject implements IEquatable, IComparable
34
{
35
    /**
36
     * Creates a new IntString instance.
37
     *
38
     * @param int|null     $intValue    Integer part. Default: `0` (zero).
39
     * @param string|null  $stringValue String part. Default: `''` (empty).
40
     *
41
     * @since 1.0.0-dev Allow `null` value for `$intValue`.
42
     */
43 50
    public function __construct($intValue = 0, $stringValue = '')
44
    {
45 50
        if (!(is_integer($intValue) || $intValue === null)) {
0 ignored issues
show
introduced by
The condition $intValue === null is always true.
Loading history...
46
            $args = [
47
                'position' => '1st',
48
                'expected' => typeof(0).'" or "'.typeof(null),
49
                'actual'   => typeof($intValue),
50
            ];
51
52
            $msg  = msg('Invalid argument type.');
53
            $msg .= msg(
54
                ' {position} parameter must to be an instance of "{expected}"; "{actual}" given.',
55
                $args
56
            );
57
58
            throw new InvalidArgumentException($msg);
59
        }
60
61 50
        $this->intValue = $intValue;
0 ignored issues
show
Bug introduced by
The property intValue is declared read-only in NelsonMartell\IntString.
Loading history...
62
63 50
        if (!typeof($stringValue)->canBeString()) {
64
            $args = [
65 2
                'position' => '2nd',
66 2
                'expected' => typeof('string').'", "'.typeof(null).'" or "any object convertible to string',
67 2
                'actual'   => typeof($stringValue),
68
            ];
69
70 2
            $msg  = msg('Invalid argument type.');
71 2
            $msg .= msg(
72 2
                ' {position} parameter must to be an instance of "{expected}"; "{actual}" given.',
73 2
                $args
74
            );
75
76 2
            throw new InvalidArgumentException($msg);
77
        }
78
79 48
        $this->stringValue = (string) $stringValue;
0 ignored issues
show
Bug introduced by
The property stringValue is declared read-only in NelsonMartell\IntString.
Loading history...
80 48
    }
81
82
    /**
83
     * Convert the object to an instance of ``IntString``.
84
     *
85
     * @param string|IntString $obj Object to convert to ``IntString``.
86
     *
87
     * @return IntString
88
     * @throws InvalidArgumentException if object is not a string or format is invalid.
89
     */
90 37
    public static function parse($obj)
91
    {
92 37
        if ($obj instanceof IntString) {
93
            return $obj;
94
        }
95
96 37
        if (is_integer($obj)) {
0 ignored issues
show
introduced by
The condition is_integer($obj) is always false.
Loading history...
97 19
            return new VersionComponent($obj);
98
        }
99
100
        try {
101 19
            $intValue = (integer) Text::ensureIsString($obj);
102 1
        } catch (InvalidArgumentException $e) {
103
            $args = [
104 1
                'position' => '1st',
105 1
                'expected' => 'string" or "integer',
106 1
                'actual'   => typeof($obj),
107
            ];
108
109 1
            $msg  = msg('Invalid argument type.');
110 1
            $msg .= msg(
111 1
                ' {position} parameter must to be an instance of "{expected}"; "{actual}" given.',
112 1
                $args
113
            );
114
115 1
            throw new InvalidArgumentException($msg, 1, $e);
116
        }
117
118 18
        $stringValue = ltrim($obj, "${intValue}");
119
120
        // Validate that 0 (zero) is not interpreted as '' (empty string)
121
        if ($stringValue === $obj) {
122
            $msg  = msg('Invalid argument value.');
123
            $msg .= msg(' "{0}" (string) must to start with an integer.', $obj);
124
125
            throw new InvalidArgumentException($msg);
126
        }
127
128
        return new IntString($intValue, $stringValue);
129
    }
130
131
    /**
132
     * Integer part of the instance.
133
     *
134
     * @var int
135
     */
136
    private $intValue;
137
138
    /**
139
     * String part of the instance.
140
     *
141
     * @var string
142
     */
143
    private $stringValue;
144
145
    /**
146
     * Getter for $intValue property.
147
     *
148
     * @return int
149
     */
150
    protected function getIntValue()
151
    {
152 137
        return $this->intValue;
153
    }
154
155
    /**
156
     * Getter for $stringValue property.
157
     *
158
     * @return int
159
     */
160
    protected function getStringValue()
161
    {
162 116
        return $this->stringValue;
163
    }
164
165
    /**
166
     * {@inheritDoc}
167
     */
168
    public function toString()
169
    {
170 30
        return $this->getIntValue().$this->getStringValue();
171
    }
172
173
    /**
174
     * Indicates whether the specified object is equal to the current instance.
175
     *
176
     * @param IntString|mixed $other
177
     *
178
     * @return bool
179
     */
180
    public function equals($other)
181
    {
182 15
        if ($other instanceof IntString) {
183
            if ($this->getIntValue() === $other->getIntValue()) {
184
                if ($this->getIntValue() === $other->getStringValue()) {
185
                    return true;
186
                }
187
            }
188
        }
189
190 15
        return false;
191
    }
192
193
194
    /**
195
     * Determina la posición relativa de esta instancia con respecto al
196
     * objeto especificado.
197
     * Nota: Cualquier objeto que no sea instancia de IntString se
198
     * considerará menor.
199
     *
200
     * @param IntString|mixed $other Objeto con el que se va a comparar.
201
     *
202
     * @return int Cero (0), si esta instancia es igual a $other; mayor
203
     *   a cero (>0), si es mayor a $other; menor a cero (<0), si es menor.
204
     * */
205
    public function compareTo($other)
206
    {
207
        $r = $this->equals($other) ? 0 : 9999;
208
209
        if ($r != 0) {
210
            if ($other instanceof IntString) {
211
                $r = $this->intValue - $other->intValue;
212
213
                if ($r == 0) {
214
                    $r = strnatcmp($this->stringValue, $other->stringValue);
215
                }
216
            } else {
217
                $r = 1;
218
            }
219
        }
220
221
        return $r;
222
    }
223
}
224