-
-
Notifications
You must be signed in to change notification settings - Fork 373
/
Enum.pm
69 lines (55 loc) · 2.13 KB
/
Enum.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
66
67
68
69
my class Enum does Associative {
has $.key;
has $.value;
method new(:$key, Mu :$value) { nqp::create(self).BUILD($key, $value) }
method BUILD($!key, Mu $!value) { self }
multi method ACCEPTS(Enum:D: Associative:D $topic) {
$topic{$!key} ~~ $!value
}
multi method ACCEPTS(Enum:D: Mu $topic) {
my $method = $!key;
$topic."$method"() === $!value;
}
method antipair(Enum:D:) { self.new(key => $!value, value => $!key) }
multi method keys(Enum:D:) { ($!key,).list }
multi method kv(Enum:D:) { $!key, $!value }
multi method values(Enum:D:) { ($!value,).list }
multi method pairs(Enum:D:) { (self,).list }
multi method antipairs(Enum:D:) { self.new(key => $!value, value => $!key) }
multi method invert(Enum:D:) { $!value »=>» $!key }
multi method Str(Enum:D:) { $!key ~ "\t" ~ $!value }
multi method gist(Enum:D:) {
if nqp::istype($!key, Enum) {
'(' ~ $!key.gist ~ ') => ' ~ $!value.gist;
} else {
$!key.gist ~ ' => ' ~ $!value.gist;
}
}
multi method perl(Enum:D: :$arglist) {
if nqp::istype($!key, Enum) {
'(' ~ $!key.perl ~ ') => ' ~ $!value.perl;
} elsif nqp::istype($!key, Str) and !$arglist and $!key ~~ /^ [<alpha>\w*] +% <[\-']> $/ {
if nqp::istype($!value,Bool) {
':' ~ '!' x !$!value ~ $!key;
} else {
':' ~ $!key ~ '(' ~ $!value.perl ~ ')';
}
} else {
$!key.perl ~ ' => ' ~ $!value.perl;
}
}
method fmt($format = "%s\t%s") {
sprintf($format, $!key, $!value);
}
multi method AT-KEY(Enum:D: $key) { $key eq $!key ?? $!value !! Mu }
multi method EXISTS-KEY(Enum:D: $key) { $key eq $!key }
method FLATTENABLE_LIST() { nqp::list() }
method FLATTENABLE_HASH() { nqp::hash($!key, $!value) }
}
multi sub infix:<eqv>(Enum:D $a, Enum:D $b) {
$a.WHAT === $b.WHAT && $a.key eqv $b.key && $a.value eqv $b.value
}
multi sub infix:<cmp>(Enum:D \a, Enum:D \b) {
(a.key cmp b.key) || (a.value cmp b.value)
}
# vim: ft=perl6 expandtab sw=4