Completed
Push — master ( 5096ba...da0857 )
by Peter
07:17
created

IPv6Interval::union()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 2
1
<?php
2
3
/**
4
 * GpsLab component.
5
 *
6
 * @author    Peter Gribanov <[email protected]>
7
 * @copyright Copyright (c) 2016, Peter Gribanov
8
 * @license   http://opensource.org/licenses/MIT
9
 */
10
11
namespace GpsLab\Component\Interval\IPv6;
12
13
use GpsLab\Component\Interval\Exception\IncorrectIntervalException;
14
use GpsLab\Component\Interval\Exception\InvalidIntervalFormatException;
15
use GpsLab\Component\Interval\IntervalComparator;
16
use GpsLab\Component\Interval\ComparableIntervalInterface;
17
use GpsLab\Component\Interval\IntervalPointInterface;
18
use GpsLab\Component\Interval\IntervalType;
19
20
class IPv6Interval implements ComparableIntervalInterface
21
{
22
    /**
23
     * @var string
24
     */
25
    const REGEXP = '/^
26
        (?:\(|\[)                                  # start type char
27
        \s*
28
        (?<start>'.IPv6IntervalPoint::IPV6_ADDR.') # start point
29
        \s*,\s*                                    # separator
30
        (?<end>'.IPv6IntervalPoint::IPV6_ADDR.')   # end point
31
        \s*
32
        (?:\)|\])                                  # end type char
33
    $/x';
34
35
    /**
36
     * @var IntervalType
37
     */
38
    private $type;
39
40
    /**
41
     * @var IntervalComparator
42
     */
43
    private $comparator;
44
45
    /**
46
     * @var IPv6IntervalPoint
47
     */
48
    private $start;
49
50
    /**
51
     * @var IPv6IntervalPoint
52
     */
53
    private $end;
54
55
    /**
56
     * @param IPv6IntervalPoint $start
57
     * @param IPv6IntervalPoint $end
58
     * @param IntervalType $type
59
     */
60 4
    private function __construct(IPv6IntervalPoint $start, IPv6IntervalPoint $end, IntervalType $type)
61
    {
62 4
        if ($start->gte($end)) {
63
            throw IncorrectIntervalException::create();
64
        }
65
66 4
        $this->type = $type;
67 4
        $this->start = $start;
68 4
        $this->end = $end;
69 4
        $this->comparator = new IntervalComparator($this);
70 4
    }
71
72
    /**
73
     * @param string $start
74
     * @param string $end
75
     * @param IntervalType $type
76
     *
77
     * @return self
78
     */
79 4
    public static function create($start, $end, IntervalType $type)
80
    {
81 4
        return new self(new IPv6IntervalPoint($start), new IPv6IntervalPoint($end), $type);
82
    }
83
84
    /**
85
     * @param string $start
86
     * @param string $end
87
     *
88
     * @return self
89
     */
90 1
    public static function closed($start, $end)
91
    {
92 1
        return static::create($start, $end, IntervalType::closed());
93
    }
94
95
    /**
96
     * @param string $start
97
     * @param string $end
98
     *
99
     * @return self
100
     */
101 1
    public static function halfClosed($start, $end)
102
    {
103 1
        return static::create($start, $end, IntervalType::halfClosed());
104
    }
105
106
    /**
107
     * @param string $start
108
     * @param string $end
109
     *
110
     * @return self
111
     */
112 1
    public static function halfOpen($start, $end)
113
    {
114 1
        return static::create($start, $end, IntervalType::halfOpen());
115
    }
116
117
    /**
118
     * @param string $start
119
     * @param string $end
120
     *
121
     * @return self
122
     */
123 1
    public static function open($start, $end)
124
    {
125 1
        return static::create($start, $end, IntervalType::open());
126
    }
127
128
    /**
129
     * Create interval from string.
130
     *
131
     * Example formats for all interval types:
132
     *   [fe80::, febf::]
133
     *   (fe80::, febf::]
134
     *   [fec0::, feff::)
135
     *   (fec0::, feff::)
136
     *
137
     * Spaces are ignored in format.
138
     *
139
     * @param string $string
140
     *
141
     * @return self
142
     */
143 4
    public static function fromString($string)
144
    {
145 4
        if (!preg_match(self::REGEXP, $string, $match)) {
146
            $ipv6 = implode(':', array_fill(0, 8, 'ffff'));
147
            throw InvalidIntervalFormatException::create(sprintf('[%s, %s]', $ipv6, $ipv6), $string);
148
        }
149
150 4
        return self::create($match['start'], $match['end'], IntervalType::fromString($string));
151
    }
152
153
    /**
154
     * Checks if this interval is equal to the specified interval.
155
     *
156
     * @param IPv6Interval $interval
157
     *
158
     * @return bool
159
     */
160
    public function equal(IPv6Interval $interval)
161
    {
162
        return $this->comparator->equal($interval);
163
    }
164
165
    /**
166
     * Does this interval contain the specified point.
167
     *
168
     * @param string $point
169
     *
170
     * @return bool
171
     */
172
    public function contains($point)
173
    {
174
        return $this->comparator->contains(new IPv6IntervalPoint($point));
175
    }
176
177
    /**
178
     * Does this interval intersect the specified interval.
179
     *
180
     * @param IPv6Interval $interval
181
     *
182
     * @return bool
183
     */
184
    public function intersects(IPv6Interval $interval)
185
    {
186
        return $this->comparator->intersects($interval);
187
    }
188
189
    /**
190
     * Gets the intersection between this interval and another interval.
191
     *
192
     * @param IPv6Interval $interval
193
     *
194
     * @return self|null
195
     */
196
    public function intersection(IPv6Interval $interval)
197
    {
198
        return $this->comparator->intersection($interval);
199
    }
200
201
    /**
202
     * Gets the covered interval between this Interval and another interval.
203
     *
204
     * @param IPv6Interval $interval
205
     *
206
     * @return self
207
     */
208
    public function cover(IPv6Interval $interval)
209
    {
210
        return $this->comparator->cover($interval);
211
    }
212
213
    /**
214
     * Gets the gap between this interval and another interval.
215
     *
216
     * @param IPv6Interval $interval
217
     *
218
     * @return self|null
219
     */
220
    public function gap(IPv6Interval $interval)
221
    {
222
        return $this->comparator->gap($interval);
223
    }
224
225
    /**
226
     * Does this interval abut with the interval specified.
227
     *
228
     * @param IPv6Interval $interval
229
     *
230
     * @return bool
231
     */
232
    public function abuts(IPv6Interval $interval)
233
    {
234
        return $this->comparator->abuts($interval);
235
    }
236
237
    /**
238
     * Joins the interval between the adjacent.
239
     *
240
     * @param IPv6Interval $interval
241
     *
242
     * @return self|null
243
     */
244
    public function join(IPv6Interval $interval)
245
    {
246
        return $this->comparator->join($interval);
247
    }
248
249
    /**
250
     * Gets the union between this interval and another interval.
251
     *
252
     * @param IPv6Interval $interval
253
     *
254
     * @return self|null
255
     */
256
    public function union(IPv6Interval $interval)
257
    {
258
        return $this->comparator->union($interval);
259
    }
260
261
    /**
262
     * The point is before the interval.
263
     *
264
     * @param string $point
265
     *
266
     * @return bool
267
     */
268 4
    public function before($point)
269
    {
270 4
        return $this->comparator->before(new IPv6IntervalPoint($point));
271
    }
272
273
    /**
274
     * The point is after the interval.
275
     *
276
     * @param string $point
277
     *
278
     * @return bool
279
     */
280
    public function after($point)
281
    {
282
        return $this->comparator->after(new IPv6IntervalPoint($point));
283
    }
284
285
    /**
286
     * @return IntervalType
287
     */
288 4
    public function type()
289
    {
290 4
        return $this->type;
291
    }
292
293
    /**
294
     * @return string
295
     */
296 4
    public function start()
297
    {
298 4
        return (string) $this->start;
299
    }
300
301
    /**
302
     * @return string
303
     */
304 4
    public function end()
305
    {
306 4
        return (string) $this->end;
307
    }
308
309
    /**
310
     * @return IPv6IntervalPoint
311
     */
312 4
    public function startPoint()
313
    {
314 4
        return $this->start;
315
    }
316
317
    /**
318
     * @return IPv6IntervalPoint
319
     */
320 4
    public function endPoint()
321
    {
322 4
        return $this->end;
323
    }
324
325
    /**
326
     * Returns a copy of this Interval with the start point altered.
327
     *
328
     * @param IntervalPointInterface|IPv6IntervalPoint $start
329
     *
330
     * @return self
331
     */
332
    public function withStart(IntervalPointInterface $start)
333
    {
334
        return new self($start, $this->end, $this->type);
0 ignored issues
show
Compatibility introduced by
$start of type object<GpsLab\Component\...IntervalPointInterface> is not a sub-type of object<GpsLab\Component\...IPv6\IPv6IntervalPoint>. It seems like you assume a concrete implementation of the interface GpsLab\Component\Interval\IntervalPointInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
335
    }
336
337
    /**
338
     * Returns a copy of this Interval with the end point altered.
339
     *
340
     * @param IntervalPointInterface|IPv6IntervalPoint $end
341
     *
342
     * @return self
343
     */
344
    public function withEnd(IntervalPointInterface $end)
345
    {
346
        return new self($this->start, $end, $this->type);
0 ignored issues
show
Compatibility introduced by
$end of type object<GpsLab\Component\...IntervalPointInterface> is not a sub-type of object<GpsLab\Component\...IPv6\IPv6IntervalPoint>. It seems like you assume a concrete implementation of the interface GpsLab\Component\Interval\IntervalPointInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
347
    }
348
349
    /**
350
     * Returns a copy of this Interval with the interval type altered.
351
     *
352
     * @param IntervalType $type
353
     *
354
     * @return self
355
     */
356
    public function withType(IntervalType $type)
357
    {
358
        return new self($this->start, $this->end, $type);
359
    }
360
361
    /**
362
     * @return string
363
     */
364 4
    public function __toString()
365
    {
366 4
        return $this->type->formatInterval($this);
367
    }
368
}
369