Completed
Pull Request — master (#2)
by Julien
02:21
created

PreReleaseComparator::compare()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.2
c 0
b 0
f 0
cc 4
eloc 10
nc 4
nop 2
1
<?php
2
declare(strict_types = 1);
3
4
namespace SemVer\SemVer;
5
6
final class PreReleaseComparator
7
{
8
    /**
9
     * @param Version $version1
10
     * @param Version $version2
11
     *
12
     * @return int
13
     */
14
    public static function compare(Version $version1, Version $version2) : int
15
    {
16
        $preRelease1 = $version1->getPreRelease();
17
        $preRelease2 = $version2->getPreRelease();
18
19
        $leftPreReleaseIsEmpty = '' === $preRelease1;
20
        $rightPreReleaseIsEmpty = '' === $preRelease2;
21
        if ($rightPreReleaseIsEmpty !== $leftPreReleaseIsEmpty) {
22
            return $leftPreReleaseIsEmpty ? 1 : -1;
23
        }
24
25
        if ($leftPreReleaseIsEmpty) {
26
            return 0;
27
        }
28
29
        return self::compareIdentifiers(explode('.', $preRelease1), explode('.', $preRelease2));
30
    }
31
32
    /**
33
     * @param array $preReleaseIdentifiers1
34
     * @param array $preReleaseIdentifiers2
35
     *
36
     * @return int
37
     */
38
    private static function compareIdentifiers(array $preReleaseIdentifiers1, array $preReleaseIdentifiers2) : int
39
    {
40
        do {
41
            $preReleasePart1 = array_shift($preReleaseIdentifiers1);
42
            $preReleasePart2 = array_shift($preReleaseIdentifiers2);
43
44
            $compare = self::compareIdentifier($preReleasePart1, $preReleasePart2);
45
46
            if (0 !== $compare) {
47
                return $compare;
48
            }
49
        } while (count($preReleaseIdentifiers1) || count($preReleaseIdentifiers2));
50
51
        return 0;
52
    }
53
54
    /**
55
     * @param string $preReleasePart1
56
     * @param string $preReleasePart2
57
     *
58
     * @return int
59
     */
60
    private static function compareIdentifier(string $preReleasePart1, string $preReleasePart2) : int
61
    {
62
        if (null === $preReleasePart1) {
63
            return -1;
64
        }
65
66
        if (null === $preReleasePart2) {
67
            return 1;
68
        }
69
70
        $mineIsInt = self::isInt($preReleasePart1);
71
        $theirIsInt = self::isInt($preReleasePart2);
72
73
        if ($mineIsInt !== $theirIsInt) {
74
            return $mineIsInt ? -1 : 1;
75
        }
76
        
77
        if ($mineIsInt) {
78
            return ((int)$preReleasePart1) <=> ((int)$preReleasePart2);
79
        }
80
81
        return $preReleasePart1 <=> $preReleasePart2;
82
    }
83
84
    /**
85
     * @param string $identifier
86
     *
87
     * @return bool
88
     */
89
    private static function isInt(string $identifier)
90
    {
91
        return ctype_digit($identifier) && strpos($identifier, '00') !== 0;
92
    }
93
}
94