Skip to content

Instantly share code, notes, and snippets.

Created February 26, 2015 02:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/6d3cb3ee4ddc0678db90 to your computer and use it in GitHub Desktop.
Save anonymous/6d3cb3ee4ddc0678db90 to your computer and use it in GitHub Desktop.
MacBookProRetinaFCO:JSON_API fernando$ cat URI.pm6
class URI {
grammar URIGrammar is export {
regex proto { "http" "s"? }
regex octect { \d**1..3 <?{$/ <= 255}> }
rule ip { <.octect> "." <.octect> "." <.octect> "." <.octect> { make $<octect>.join(".")} }
regex domain { [ <[\w+-]>+ "." ]+ \w**2..* [ \w**2 ]? }
regex host { <.domain> | <.ip> { make $<domain> if $<domain>:exists; make $<ip> } }
regex path { "/" [ <[\w+.-]>+ "/"? ]* }
regex key { \w+ [ "[" <key> "]"]? }
regex value { <[\w+.-]>* }
rule pair { <key> "=" <value> }
rule qs { <pair> [ "&" <qs> ]? "&"* }
regex fragment { .+ }
regex port { \d+ <?{ $/ <= 65535 }> }
rule TOP {^ [ <proto> ":" ]? [ "//" <host> [ ":" <port> ]? ]? <path>? [ "?" <qs> ]? [ "#" <fragment> ]? $}
}
has Str $.uri is rw;
has Str $.proto is rw;
has Str $.host is rw;
has Int $.port is rw;
has Str $.path is rw;
has $.qs is rw;
has Str $.fragment is rw;
has Bool $.changed = False;
method new (Str $uri) {self.bless(:$uri)}
submethod BUILD (:$!uri) {
self!set-data;
}
method !set-data {
my $res = URIGrammar.parse($!uri);
$!proto = $res<proto>.Str;
$!host = $res<host>.Str;
$!port = $res<port>.Int;
$!path = $res<path>.Str;
$!qs = $res<qs>.Str;
$!fragment = $res<fragment>.Str;
}
method !set-uri {
my $uri;
if $!proto:defined or $!host:defined {
$uri ~= $!proto ~ ":" if $!proto:defined;
$uri ~= "//";
$uri ~= $!host if $!host:defined;
$uri ~= ":" ~ $!port if $!port:defined;
}
$uri ~= $!path;
$uri ~= $!qs if $!qs:defined;
$uri ~= $!fragment if $!fragment:defined;
$!uri = $uri
}
method gist {
$.uri
}
<uri proto host port path qs fragment>.map(-> $meth {
$?CLASS.^find_method($meth).wrap(my method () is rw {
Proxy.new:
STORE => method ($val) {$!changed = True; callsame() = $val},
FETCH => method () {nextsame}
})
});
$?CLASS.^find_method("uri").wrap(my method () is rw {
self!set-uri if $!changed;
callsame
});
<proto host port path qs fragment>.map(-> $meth {
$?CLASS.^find_method($meth).wrap(my method () is rw {
self!set-data if $!changed;
callsame
})
});
}
MacBookProRetinaFCO:JSON_API fernando$ perl6 -I. -e '
use URI;
$a = URI.new(q"http://pudim.com.br:8080/path/index.html?key[1]=val1&key[2]=value2");
say $a;
$a.port = 123;
$a.changed.say;
$a.say;
'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment