#! /usr/bin/env false use v6.d; use URL::Grammar; use URL::Grammar::Actions; unit class URL; has Str $.scheme; has Str $.username; has Str $.password; has Str $.hostname; has Int $.port; has @.path; has %.query; has Str $.fragment; multi method new ( Str:D $url, ) { my %match = URL::Grammar.parse($url, actions => URL::Grammar::Actions).made; die "'$url' failed to parse. Please report the URL you tried to p.spek+perl6@tyil.work." unless %match; samewith( |%match, path => %match.list, ); } multi method new ( Str :$scheme, Str :$username, Str :$password, Str :$hostname, Int :$port, :@path = [], :%query = {}, Str :$fragment, ) { self.bless( :$scheme, :$username, :$password, :$hostname, :$port, :@path, :%query, :$fragment, ); } #| Append one or more parts to the path of the URL. method add-path ( *@parts, --> URL ) { return self.new(|self.Hash) unless @parts; self.new( |self.Hash, path => [|@!path, |@parts], ); } #| Append one or more query parameters to the URL. method add-query ( *%parts, --> URL ) { return self.new(|self.Hash) unless %parts; self.new( |self.Hash, query => %(|%!query, |%parts), ); } method Hash ( --> Hash ) { { :$!scheme, :$!username, :$!password, :$!hostname, :$!port, :@!path, :%!query, :$!fragment, } } multi method Str ( --> Str ) { my $s = $!scheme ~ "://"; $s ~= "{self.Str(:userinfo)}@" if $!username; $s ~= $!hostname; $s ~= ":$!port" if $!port; $s ~= "/{self.Str(:path)}" if @!path; $s ~= "?{self.Str(:query)}" if %!query; $s ~= "#$!fragment" if $!fragment; $s; } multi method Str ( :$path! where { $_ }, --> Str ) { @!path.join("/"); } multi method Str ( :$query! where { $_ }, --> Str ) { %!query.keys.sort.map({ "$_={%!query{$_}}" }).join("&") } multi method Str ( :$userinfo! where { $_ }, --> Str ) { return "$!username:$!password" if $!password; $!username // ""; } =begin pod =NAME URL =AUTHOR Patrick Spek =VERSION 0.2.1 =head1 Synopsis =head1 Description =head1 Examples =head1 See also =end pod # vim: ft=perl6 noet