/
URI.pm
120 lines (93 loc) · 2.83 KB
/
URI.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
unit class November::URI;
# This class used to be called just 'URI', but there was a collision with
# the eponymous class in the 'uri' project. Arguably, that class has more
# rights to that name, so this one was renamed. Since the 'uri' project
# ought to cover the same functionality as this class, maybe long-term we
# could switch to using that instead. One more dependency, but less code
# duplication across projects.
use November::URI::Grammar;
# RAKUDO: Match object does not do assignment properly :(
#my Match $.parts; dies in init with 'Type mismatch in assignment';
# workaround:
has $.uri;
has @.chunks;
submethod BUILD(:$uri) {
# clear string before parsing
my $c_str = $uri;
$c_str .= subst(/^ \s* ['<' | '"'] /, '');
$c_str .= subst(/ ['>' | '"'] \s* $/, '');
November::URI::Grammar.parse($c_str);
unless $/ { die "Could not parse URI: $uri" }
$!uri = $/;
@!chunks = @($<path><chunk>) || ('');
}
method scheme {
my $s = $.uri<scheme> || '';
# RAKUDO: return 1 if use ~ below die because can`t do lc on Math after
return ~$s.lc;
}
method authority {
my $a = $.uri<authority> || '';
# RAKUDO: return 1 if use ~ below die because can`t do lc on Math after
return ~$a.lc;
}
method host {
#RAKUDO: $.uri<authority>[0]<host> return full <authority> now
my $h = ~$.uri<authority><host>;
return $h.lc || '';
}
method port {
# TODO: send rakudobug
# RAKUDO: $.uri<authority><port> return full <authority> now
# workaround:
item $.uri<authority><port> || '';
}
method path {
my $p = ~$.uri<path> || '';
return $p.lc;
}
method absolute {
# RAKUDO: The grammar uses <slash>?, so this should be either Nil or a
# Match object. But Rakudo returns [] or [Match] instead, so we must use
# || instead of // to test.
return ?($.uri<path><slash> || $.scheme);
}
method relative {
# Rakudo: Must use || instead of //, see above.
return !($.uri<path><slash> || $.scheme);
}
method query {
item $.uri<query> || '';
}
method frag {
my $f = $.uri<fragment> || '';
return ~$f.lc;
}
method fragment { $.frag }
method Str() {
my $str;
$str ~= $.scheme if $.scheme;
$str ~= '://' ~ $.authority if $.authority;
$str ~= $.path;
$str ~= '?' ~ $.query if $.query;
$str ~= '#' ~ $.frag if $.frag;
return $str;
}
=begin pod
=head NAME
November::URI — Uniform Resource Identifiers (absolute and relative)
=head SYNOPSYS
use November::URI;
my $u = November::URI.new;
$u.init('http://example.com/foo/bar?tag=woow#bla');
my $scheme = $u.scheme;
my $authority = $u.authority;
my $host = $u.host;
my $port = $u.port;
my $path = $u.path;
my $query = $u.query;
my $frag = $u.frag; # or $u.fragment;
my $is_absolute = $u.absolute;
my $is_relative = $u.relative;
=end pod
# vim:ft=perl6