ruby's URI
is a very simple way to deal with...well, uri.
the problem is the search
(query string).
dealing with search string by hand is really annoying and error prune. as the search has no form specified on the RFC, we can play with it, it opens a lot of interesting ideas to providing a better way to manage it.
an example is a search that works with key/values pairs that can contains duplicated keys:
a=ok&a=meh
if this is not a good idea for you application, we could implement a query string that uses a hashmap as storage.
a required interface is:
interface QueryString {
static QueryString from_string(String query_string);
String to_s();
}
class HashmapSearch
def self.from_string(query_string)
ary = URI.decode_www_form(query_string || '')
new(ary)
end
def initialize(query)
# if a keys is present many times,
# the last one will get on the hash.
@query = query.empty? ? {} : Hash[query]
end
def to_s
URI.encode_www_form(@query)
end
# operations is up to you!
def add(key, value)
@query[key] = value
end
def [](key)
@query[key]
end
def remove(key)
@query = @query.reject do |pair|
k, = pair
k == key
end
end
end
getting everything together...
irb> a = SimpleUrl::Url.new('https://okokok.com/path?a=1&a=2', HashmapSearch)
=> #<SimpleUrl::Url:0x00000000017447e8 @url=#<URI::HTTPS https://okokok.com/path?a=1&a=2>, @query_string_class=HashmapSearch, @query=#<HashmapSea...
irb> a.query
=> #<HashmapSearch:0x0000000001744338 @query={"a"=>"2"}>
irb> a.url.path = "/asdf"
=> "/asdf"
irb> a.to_s
=> "https://okokok.com/asdf?a=2"
irb> a.query.add('b', 2)
=> 2
irb> a.to_s
=> "https://okokok.com/path?a=2&b=2"
irb(main):039:0> a.query.add('a', 43)
=> 43
irb(main):040:0> a.to_s
=> "https://okokok.com/path?a=43&b=2"
irb> a = SimpleUrl::Url.new('https://okokok.com/path?a=1&a=2', SimpleUrl::KeyValueQueryString)
=> #<SimpleUrl::Url:0x0000000003c32f78 @url=#<URI::HTTPS https://okokok.com/path?a=1&a=2>, @query_string_class=SimpleUrl::KeyValueQueryString, @q...
irb> a.query.to_s
=> "a=1&a=2"
irb(main):043:0> a.query.add('a', 3)
=> [["a", "1"], ["a", "2"], ["a", 3]]
irb(main):044:0> a.query.to_s
=> "a=1&a=2&a=3"
This code is released under Unlicense
.
See License