/
Enum.pm
71 lines (57 loc) · 2.21 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
70
71
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 key(Enum:D:) { $!key }
method value(Enum:D:) { $!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