-
-
Notifications
You must be signed in to change notification settings - Fork 373
/
Version.pm
65 lines (55 loc) · 1.72 KB
/
Version.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
class Version {
has @.parts;
has Bool $.plus = False;
multi method new(Str() $s) {
my @parts = $s.comb(/:r '*' || \d+ || <.alpha>+/);
for @parts {
$_ .= Numeric if .Numeric.defined ;
$_ = * if $_ eq '*';
}
self.bless(
:parts(@parts),
:plus(?$s.chars && substr($s,*-1) eq '+'),
);
};
multi method Str(Version:D:) {
@!parts.map({ nqp::istype($_,Whatever) ?? '*' !! $_}).join('.')
~ ($!plus ?? '+' !! '');
}
multi method gist(Version:D:) { 'v' ~ self.Str }
multi method perl(Version:D:) {
self.^name ~ ".new('" ~ self.Str ~ "')";
}
multi method ACCEPTS(Version:D: Version:D $other) {
for @!parts.kv -> $i, $v {
next if nqp::istype($v,Whatever);
my $o = $other.parts[$i];
return True unless defined $o;
next if nqp::istype($o,Whatever);
return $.plus if $o after $v;
return False if $o before $v;
}
True;
}
multi method WHICH(Version:D:) {
my $s := join '|', self.^name, self.Str;
nqp::box_s(nqp::unbox_s($s), ObjAt);
}
}
multi sub infix:<eqv>(Version:D $a, Version:D $b) {
$a.WHAT === $b.WHAT && $a.Str eq $b.Str
}
multi sub infix:<cmp>(Version:D $a, Version:D $b) {
proto vnumcmp(|) { * }
multi vnumcmp(Str, Int) { Order::Less }
multi vnumcmp(Int, Str) { Order::More }
multi vnumcmp($av, $bv) { $av cmp $bv }
my @av = $a.parts.values;
my @bv = $b.parts.values;
while @av || @bv {
my $cmp = vnumcmp(@av.shift // 0, @bv.shift // 0);
return $cmp if $cmp != Order::Same;
}
$a.plus cmp $b.plus;
}
# vim: ft=perl6 expandtab sw=4