/
Identity.rakumod
84 lines (72 loc) · 2.62 KB
/
Identity.rakumod
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
72
73
74
75
76
77
78
79
80
81
82
83
84
class Zef::Identity {
has $.name;
has $.version;
has $.auth;
has $.api;
has $.from;
my grammar REQUIRE {
regex TOP { ^^ <name> [':' <key> <value>]* $$ }
regex name { <-restricted +name-sep>+ }
token key { <-restricted>+ }
regex value { '<' ~ '>' [<( [[ <!before \>|\<|\\> . ]+?]* %% ['\\' . ]+ )>] }
token restricted { [':' | '<' | '>' | '(' | ')'] }
token name-sep { < :: > }
}
my class REQUIRE::Actions {
method TOP($/) { make %('name'=> $/<name>.made, %($/<key> Z=> $/<value>>>.ast)) if $/ }
method name($/) { make $/.Str }
method key($/) { my $str = make $/.Str; ($str eq 'ver') ?? 'version' !! $str }
method value($/) { make $/.Str }
}
proto method new(|) {*}
multi method new(Str :$name!, :ver(:$version), :$auth, :$api, :$from) {
self.bless(:$name, :$version, :$auth, :$api, :$from);
}
multi method new(Str $id) {
if $id.starts-with('.' | '/') {
self.bless(
name => $id,
version => '',
auth => '',
api => '',
from => '',
);
}
elsif REQUIRE.parse($id, :actions(REQUIRE::Actions)).ast -> $ident {
self.bless(
name => ~($ident<name> // ''),
version => ~($ident<ver version>.first(*.defined) // ''),
auth => ~($ident<auth> // '').trans(['\<', '\>'] => ['<', '>']),
api => ~($ident<api> // ''),
from => ~($ident<from> || 'Raku'),
);
}
}
# Acme::Foo::SomeModule:auth<cpan:ugexe>:ver('1.0')
method identity {
$!name
~ (($!version // '' ) ne ('*' | '') ?? ":ver<" ~ $!version ~ ">" !! '')
~ (($!auth // '' ) ne ('*' | '') ?? ":auth<" ~ $!auth ~ ">" !! '')
~ (($!api // '' ) ne ('*' | '') ?? ":api<" ~ $!api ~ ">" !! '')
~ (($!from // '' ) ne ('Raku' | 'Perl6' | '') ?? ":from<" ~ $!from ~ ">" !! '');
}
method hash {
my %hash;
%hash<name> = $!name // '';
%hash<ver> = $!version // '';
%hash<auth> = $!auth // '';
%hash<api> = $!api // '';
%hash<from> = $!from // '';
%hash;
}
}
sub str2identity($str) is export {
# todo: when $str is a path
Zef::Identity.new($str).?identity // $str;
}
sub identity2hash($identity) is export {
Zef::Identity.new($identity).?hash;
}
sub hash2identity($hash) is export {
Zef::Identity.new(|$hash).?identity;
}