diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..280f6ae --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +## v1.0.0 + +- Initial Release + +## v2.0.0 + +- Removed types.Uri. Now gluri uses the stdlib Uri type (and empty) diff --git a/gleam.toml b/gleam.toml index db9a705..f584cf3 100644 --- a/gleam.toml +++ b/gleam.toml @@ -1,5 +1,5 @@ name = "gluri" -version = "1.0.0" +version = "2.0.0" # Fill out these fields if you intend to generate HTML documentation or publish # your project to the Hex package manager. diff --git a/manifest.toml b/manifest.toml index 42d98c9..0856ff9 100644 --- a/manifest.toml +++ b/manifest.toml @@ -14,7 +14,7 @@ packages = [ { name = "gleam_json", version = "3.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_json", source = "hex", outer_checksum = "874FA3C3BB6E22DD2BB111966BD40B3759E9094E05257899A7C08F5DE77EC049" }, { name = "gleam_otp", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "7987CBEBC8060B88F14575DEF546253F3116EBE2A5DA6FD82F38243FCE97C54B" }, { name = "gleam_regexp", version = "1.1.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_regexp", source = "hex", outer_checksum = "9C215C6CA84A5B35BB934A9B61A9A306EC743153BE2B0425A0D032E477B062A9" }, - { name = "gleam_stdlib", version = "0.62.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "0080706D3A5A9A36C40C68481D1D231D243AF602E6D2A2BE67BA8F8F4DFF45EC" }, + { name = "gleam_stdlib", version = "0.63.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "5E216C7D5E8BE22359C9D7DAA2CFBD66039BC12565542F34CD033C5BB57071ED" }, { name = "gleam_time", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_time", source = "hex", outer_checksum = "DCDDC040CE97DA3D2A925CDBBA08D8A78681139745754A83998641C8A3F6587E" }, { name = "gleam_yielder", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_yielder", source = "hex", outer_checksum = "8E4E4ECFA7982859F430C57F549200C7749823C106759F4A19A78AEA6687717A" }, { name = "gleeunit", version = "1.6.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "FDC68A8C492B1E9B429249062CD9BAC9B5538C6FBF584817205D0998C42E1DAC" }, diff --git a/src/gluri.gleam b/src/gluri.gleam index 2099734..1243357 100644 --- a/src/gluri.gleam +++ b/src/gluri.gleam @@ -3,10 +3,9 @@ import gleam/int import gleam/list import gleam/option.{Some} import gleam/string -import gleam/uri +import gleam/uri.{type Uri, Uri} import gluri/internal/parser import gluri/internal/utils -import gluri/types.{type Uri, Uri} /// Parses a string to the RFC3986 standard. /// `Error` is returned if it fails parsing. @@ -151,32 +150,6 @@ pub fn are_equivalent(uri1: Uri, uri2: Uri) -> Bool { uri1 == uri2 } -/// Converts a uri library Uri value to the Gleam stdlib Uri value -pub fn to_uri(uri: Uri) -> uri.Uri { - uri.Uri( - uri.scheme, - uri.userinfo, - uri.host, - uri.port, - uri.path, - uri.query, - uri.fragment, - ) -} - -/// Converts a Gleam stdlib Uri value to a uri library Uri value -pub fn from_uri(uri: uri.Uri) -> Uri { - Uri( - uri.scheme, - uri.userinfo, - uri.host, - uri.port, - uri.path, - uri.query, - uri.fragment, - ) -} - /// Decodes a percent encoded string. /// /// Will return an `Error` if the encoding is not valid diff --git a/src/gluri/internal/parser.gleam b/src/gluri/internal/parser.gleam index 06e3f10..81014ce 100644 --- a/src/gluri/internal/parser.gleam +++ b/src/gluri/internal/parser.gleam @@ -4,11 +4,10 @@ import gleam/list.{Continue, Stop} import gleam/option.{None, Some} import gleam/result import gleam/string +import gleam/uri.{type Uri, Uri, empty} import gluri/internal/utils import splitter -import gluri/types.{type Uri, Uri, empty_uri} - pub fn parse(uri: String) -> Result(Uri, Nil) { case parse_scheme(uri) { Ok(#(scheme, rest)) -> { @@ -42,9 +41,9 @@ fn parse_query(str: String) -> Result(#(Uri, String), Nil) { case str { "?" <> rest -> { let #(query, rest) = get_multiple_optional(parse_query_fragment, rest) - Ok(#(Uri(..empty_uri, query: Some(query)), rest)) + Ok(#(Uri(..empty, query: Some(query)), rest)) } - _ -> Ok(#(empty_uri, str)) + _ -> Ok(#(empty, str)) } } @@ -52,9 +51,9 @@ fn parse_fragment(str: String) -> Result(#(Uri, String), Nil) { case str { "#" <> rest -> { let #(fragment, rest) = get_multiple_optional(parse_query_fragment, rest) - Ok(#(Uri(..empty_uri, fragment: Some(fragment)), rest)) + Ok(#(Uri(..empty, fragment: Some(fragment)), rest)) } - _ -> Ok(#(empty_uri, str)) + _ -> Ok(#(empty, str)) } } diff --git a/src/gluri/internal/utils.gleam b/src/gluri/internal/utils.gleam index 5733384..ac4bd13 100644 --- a/src/gluri/internal/utils.gleam +++ b/src/gluri/internal/utils.gleam @@ -4,7 +4,7 @@ import gleam/list import gleam/option.{type Option, None, Some} import gleam/result import gleam/string -import gluri/types.{type Uri, Uri} +import gleam/uri.{type Uri, Uri} import splitter.{type Splitter} pub const scheme_port = [ diff --git a/src/gluri/types.gleam b/src/gluri/types.gleam deleted file mode 100644 index 9336238..0000000 --- a/src/gluri/types.gleam +++ /dev/null @@ -1,16 +0,0 @@ -import gleam/option.{type Option, None} - -pub type Uri { - Uri( - scheme: Option(String), - userinfo: Option(String), - host: Option(String), - port: Option(Int), - path: String, - query: Option(String), - fragment: Option(String), - ) -} - -/// Blank Uri value -pub const empty_uri = Uri(None, None, None, None, "", None, None) diff --git a/test/gluri_test.gleam b/test/gluri_test.gleam index e74ef0b..7af9799 100644 --- a/test/gluri_test.gleam +++ b/test/gluri_test.gleam @@ -1,8 +1,8 @@ import gleam/list import gleam/option.{None, Some} +import gleam/uri.{Uri, empty} as _ import gleeunit/should import gluri as uri -import gluri/types.{Uri, empty_uri} import startest.{describe, it} pub fn main() { @@ -12,26 +12,22 @@ pub fn main() { pub fn parse_scheme_tests() { describe("scheme parsing", [ it("simple parse", fn() { - uri.parse("") |> should.equal(Ok(types.empty_uri)) + uri.parse("") |> should.equal(Ok(empty)) uri.parse("foo") - |> should.equal(Ok(Uri(..types.empty_uri, path: "foo"))) + |> should.equal(Ok(Uri(..empty, path: "foo"))) uri.parse("foo:") - |> should.equal(Ok(Uri(..types.empty_uri, scheme: Some("foo")))) + |> should.equal(Ok(Uri(..empty, scheme: Some("foo")))) uri.parse("foo:bar:nisse") - |> should.equal(Ok( - Uri(..types.empty_uri, scheme: Some("foo"), path: "bar:nisse"), - )) + |> should.equal(Ok(Uri(..empty, scheme: Some("foo"), path: "bar:nisse"))) uri.parse("foo://") - |> should.equal(Ok( - Uri(..types.empty_uri, scheme: Some("foo"), host: Some("")), - )) + |> should.equal(Ok(Uri(..empty, scheme: Some("foo"), host: Some("")))) uri.parse("foo:///") |> should.equal(Ok( - Uri(..types.empty_uri, scheme: Some("foo"), host: Some(""), path: "/"), + Uri(..empty, scheme: Some("foo"), host: Some(""), path: "/"), )) uri.parse("foo:////") |> should.equal(Ok( - Uri(..types.empty_uri, scheme: Some("foo"), host: Some(""), path: "//"), + Uri(..empty, scheme: Some("foo"), host: Some(""), path: "//"), )) }), ]) @@ -42,34 +38,28 @@ pub fn parse_userinfo_tests() { it("simple parse", fn() { uri.parse("user:password@localhost") |> should.equal(Ok( - Uri(..types.empty_uri, scheme: Some("user"), path: "password@localhost"), + Uri(..empty, scheme: Some("user"), path: "password@localhost"), )) uri.parse("user@") - |> should.equal(Ok(Uri(..types.empty_uri, path: "user@"))) + |> should.equal(Ok(Uri(..empty, path: "user@"))) uri.parse("/user@") - |> should.equal(Ok(Uri(..types.empty_uri, path: "/user@"))) + |> should.equal(Ok(Uri(..empty, path: "/user@"))) uri.parse("user@localhost") - |> should.equal(Ok(Uri(..types.empty_uri, path: "user@localhost"))) + |> should.equal(Ok(Uri(..empty, path: "user@localhost"))) uri.parse("//user@localhost") |> should.equal(Ok( - Uri(..types.empty_uri, userinfo: Some("user"), host: Some("localhost")), + Uri(..empty, userinfo: Some("user"), host: Some("localhost")), )) uri.parse("//user:password@localhost") |> should.equal(Ok( - Uri( - ..types.empty_uri, - userinfo: Some("user:password"), - host: Some("localhost"), - ), + Uri(..empty, userinfo: Some("user:password"), host: Some("localhost")), )) uri.parse("foo:/user@") - |> should.equal(Ok( - Uri(..types.empty_uri, scheme: Some("foo"), path: "/user@"), - )) + |> should.equal(Ok(Uri(..empty, scheme: Some("foo"), path: "/user@"))) uri.parse("foo://user@localhost") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), userinfo: Some("user"), host: Some("localhost"), @@ -78,7 +68,7 @@ pub fn parse_userinfo_tests() { uri.parse("foo://user:password@localhost") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), userinfo: Some("user:password"), host: Some("localhost"), @@ -88,28 +78,18 @@ pub fn parse_userinfo_tests() { it("percent encoding", fn() { uri.parse("user:%E5%90%88@%E6%B0%97%E9%81%93") |> should.equal(Ok( - Uri( - ..types.empty_uri, - scheme: Some("user"), - path: "%E5%90%88@%E6%B0%97%E9%81%93", - ), + Uri(..empty, scheme: Some("user"), path: "%E5%90%88@%E6%B0%97%E9%81%93"), )) uri.parse("%E5%90%88%E6%B0%97%E9%81%93@") - |> should.equal(Ok( - Uri(..types.empty_uri, path: "%E5%90%88%E6%B0%97%E9%81%93@"), - )) + |> should.equal(Ok(Uri(..empty, path: "%E5%90%88%E6%B0%97%E9%81%93@"))) uri.parse("/%E5%90%88%E6%B0%97%E9%81%93@") - |> should.equal(Ok( - Uri(..types.empty_uri, path: "/%E5%90%88%E6%B0%97%E9%81%93@"), - )) + |> should.equal(Ok(Uri(..empty, path: "/%E5%90%88%E6%B0%97%E9%81%93@"))) uri.parse("%E5%90%88@%E6%B0%97%E9%81%93") - |> should.equal(Ok( - Uri(..types.empty_uri, path: "%E5%90%88@%E6%B0%97%E9%81%93"), - )) + |> should.equal(Ok(Uri(..empty, path: "%E5%90%88@%E6%B0%97%E9%81%93"))) uri.parse("//%E5%90%88@%E6%B0%97%E9%81%93") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, host: Some("%E6%B0%97%E9%81%93"), userinfo: Some("%E5%90%88"), ), @@ -117,23 +97,19 @@ pub fn parse_userinfo_tests() { uri.parse("//%E5%90%88:%E6%B0%97@%E9%81%93") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, host: Some("%E9%81%93"), userinfo: Some("%E5%90%88:%E6%B0%97"), ), )) uri.parse("foo:/%E5%90%88%E6%B0%97%E9%81%93@") |> should.equal(Ok( - Uri( - ..types.empty_uri, - scheme: Some("foo"), - path: "/%E5%90%88%E6%B0%97%E9%81%93@", - ), + Uri(..empty, scheme: Some("foo"), path: "/%E5%90%88%E6%B0%97%E9%81%93@"), )) uri.parse("foo://%E5%90%88@%E6%B0%97%E9%81%93") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), userinfo: Some("%E5%90%88"), host: Some("%E6%B0%97%E9%81%93"), @@ -142,7 +118,7 @@ pub fn parse_userinfo_tests() { uri.parse("foo://%E5%90%88:%E6%B0%97@%E9%81%93") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), userinfo: Some("%E5%90%88:%E6%B0%97"), host: Some("%E9%81%93"), @@ -158,15 +134,15 @@ pub fn parse_host_tests() { describe("host parsing", [ it("simple parse", fn() { uri.parse("//hostname") - |> should.equal(Ok(Uri(..types.empty_uri, host: Some("hostname")))) + |> should.equal(Ok(Uri(..empty, host: Some("hostname")))) uri.parse("foo://hostname") |> should.equal(Ok( - Uri(..types.empty_uri, scheme: Some("foo"), host: Some("hostname")), + Uri(..empty, scheme: Some("foo"), host: Some("hostname")), )) uri.parse("foo://user@hostname") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), userinfo: Some("user"), host: Some("hostname"), @@ -175,58 +151,43 @@ pub fn parse_host_tests() { }), it("ipv4 parse", fn() { uri.parse("//127.0.0.1") - |> should.equal(Ok(Uri(..types.empty_uri, host: Some("127.0.0.1")))) + |> should.equal(Ok(Uri(..empty, host: Some("127.0.0.1")))) uri.parse("//127.0.0.1/over/there") |> should.equal(Ok( - Uri(..types.empty_uri, host: Some("127.0.0.1"), path: "/over/there"), + Uri(..empty, host: Some("127.0.0.1"), path: "/over/there"), )) uri.parse("//127.0.0.1?name=ferret") |> should.equal(Ok( - Uri( - ..types.empty_uri, - host: Some("127.0.0.1"), - query: Some("name=ferret"), - ), + Uri(..empty, host: Some("127.0.0.1"), query: Some("name=ferret")), )) uri.parse("//127.0.0.1#nose") |> should.equal(Ok( - Uri(..types.empty_uri, host: Some("127.0.0.1"), fragment: Some("nose")), + Uri(..empty, host: Some("127.0.0.1"), fragment: Some("nose")), )) uri.parse("//127.0.0.x") - |> should.equal(Ok(Uri(..types.empty_uri, host: Some("127.0.0.x")))) + |> should.equal(Ok(Uri(..empty, host: Some("127.0.0.x")))) uri.parse("//1227.0.0.1") - |> should.equal(Ok(Uri(..types.empty_uri, host: Some("1227.0.0.1")))) + |> should.equal(Ok(Uri(..empty, host: Some("1227.0.0.1")))) }), it("ipv6 parse", fn() { uri.parse("//[::127.0.0.1]") - |> should.equal(Ok(Uri(..types.empty_uri, host: Some("::127.0.0.1")))) + |> should.equal(Ok(Uri(..empty, host: Some("::127.0.0.1")))) uri.parse("//[2001:0db8:0000:0000:0000:0000:1428:07ab]") |> should.equal(Ok( - Uri( - ..types.empty_uri, - host: Some("2001:0db8:0000:0000:0000:0000:1428:07ab"), - ), + Uri(..empty, host: Some("2001:0db8:0000:0000:0000:0000:1428:07ab")), )) uri.parse("//[::127.0.0.1]/over/there") |> should.equal(Ok( - Uri(..types.empty_uri, host: Some("::127.0.0.1"), path: "/over/there"), + Uri(..empty, host: Some("::127.0.0.1"), path: "/over/there"), )) uri.parse("//[::127.0.0.1]?name=ferret") |> should.equal(Ok( - Uri( - ..types.empty_uri, - host: Some("::127.0.0.1"), - query: Some("name=ferret"), - ), + Uri(..empty, host: Some("::127.0.0.1"), query: Some("name=ferret")), )) uri.parse("//[::127.0.0.1]#nose") |> should.equal(Ok( - Uri( - ..types.empty_uri, - host: Some("::127.0.0.1"), - fragment: Some("nose"), - ), + Uri(..empty, host: Some("::127.0.0.1"), fragment: Some("nose")), )) uri.parse("//[::127.0.0.x]") |> should.be_error @@ -236,9 +197,9 @@ pub fn parse_host_tests() { }), it("ipvFuture parse", fn() { uri.parse("//[v9.abc:def]") - |> should.equal(Ok(Uri(..types.empty_uri, host: Some("v9.abc:def")))) + |> should.equal(Ok(Uri(..empty, host: Some("v9.abc:def")))) uri.parse("//[v9b.abc:def]") - |> should.equal(Ok(Uri(..types.empty_uri, host: Some("v9b.abc:def")))) + |> should.equal(Ok(Uri(..empty, host: Some("v9b.abc:def")))) uri.parse("//[vz.abc:def]") |> should.be_error uri.parse("//[va1.abc:d@ef]") |> should.be_error @@ -250,32 +211,23 @@ pub fn parse_port_tests() { describe("port parsing", [ it("simple parse", fn() { uri.parse("/:8042") - |> should.equal(Ok(Uri(..types.empty_uri, path: "/:8042"))) + |> should.equal(Ok(Uri(..empty, path: "/:8042"))) uri.parse("//:8042") - |> should.equal(Ok( - Uri(..types.empty_uri, host: Some(""), port: Some(8042)), - )) + |> should.equal(Ok(Uri(..empty, host: Some(""), port: Some(8042)))) uri.parse("//example.com:8042") |> should.equal(Ok( - Uri(..types.empty_uri, host: Some("example.com"), port: Some(8042)), + Uri(..empty, host: Some("example.com"), port: Some(8042)), )) uri.parse("foo:/:8042") - |> should.equal(Ok( - Uri(..types.empty_uri, scheme: Some("foo"), path: "/:8042"), - )) + |> should.equal(Ok(Uri(..empty, scheme: Some("foo"), path: "/:8042"))) uri.parse("foo://:8042") |> should.equal(Ok( - Uri( - ..types.empty_uri, - scheme: Some("foo"), - host: Some(""), - port: Some(8042), - ), + Uri(..empty, scheme: Some("foo"), host: Some(""), port: Some(8042)), )) uri.parse("foo://example.com:8042") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), host: Some("example.com"), port: Some(8042), @@ -286,29 +238,20 @@ pub fn parse_port_tests() { }), it("undefined port", fn() { uri.parse("/:") - |> should.equal(Ok(Uri(..types.empty_uri, path: "/:"))) + |> should.equal(Ok(Uri(..empty, path: "/:"))) uri.parse("//:") - |> should.equal(Ok(Uri(..types.empty_uri, host: Some(""), port: None))) + |> should.equal(Ok(Uri(..empty, host: Some(""), port: None))) uri.parse("//example.com:") - |> should.equal(Ok( - Uri(..types.empty_uri, host: Some("example.com"), port: None), - )) + |> should.equal(Ok(Uri(..empty, host: Some("example.com"), port: None))) uri.parse("foo:/:") - |> should.equal(Ok( - Uri(..types.empty_uri, scheme: Some("foo"), path: "/:"), - )) + |> should.equal(Ok(Uri(..empty, scheme: Some("foo"), path: "/:"))) uri.parse("foo://:") |> should.equal(Ok( - Uri(..types.empty_uri, scheme: Some("foo"), host: Some(""), port: None), + Uri(..empty, scheme: Some("foo"), host: Some(""), port: None), )) uri.parse("foo://example.com:") |> should.equal(Ok( - Uri( - ..types.empty_uri, - scheme: Some("foo"), - host: Some("example.com"), - port: None, - ), + Uri(..empty, scheme: Some("foo"), host: Some("example.com"), port: None), )) uri.parse(":") |> should.be_error uri.parse("//:x") |> should.be_error @@ -320,17 +263,15 @@ pub fn parse_path_tests() { describe("path parsing", [ it("simple parse", fn() { uri.parse("over/there") - |> should.equal(Ok(Uri(..types.empty_uri, path: "over/there"))) + |> should.equal(Ok(Uri(..empty, path: "over/there"))) uri.parse("/over/there") - |> should.equal(Ok(Uri(..types.empty_uri, path: "/over/there"))) + |> should.equal(Ok(Uri(..empty, path: "/over/there"))) uri.parse("foo:/over/there") - |> should.equal(Ok( - Uri(..types.empty_uri, scheme: Some("foo"), path: "/over/there"), - )) + |> should.equal(Ok(Uri(..empty, scheme: Some("foo"), path: "/over/there"))) uri.parse("foo://example.com/over/there") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), host: Some("example.com"), path: "/over/there", @@ -339,7 +280,7 @@ pub fn parse_path_tests() { uri.parse("foo://example.com:8042/over/there") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), host: Some("example.com"), port: Some(8042), @@ -355,12 +296,12 @@ pub fn parse_query_part_tests() { it("simple parse", fn() { uri.parse("foo:?name=ferret") |> should.equal(Ok( - Uri(..types.empty_uri, scheme: Some("foo"), query: Some("name=ferret")), + Uri(..empty, scheme: Some("foo"), query: Some("name=ferret")), )) uri.parse("foo:over/there?name=ferret") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), path: "over/there", query: Some("name=ferret"), @@ -369,7 +310,7 @@ pub fn parse_query_part_tests() { uri.parse("foo:/over/there?name=ferret") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), path: "/over/there", query: Some("name=ferret"), @@ -378,7 +319,7 @@ pub fn parse_query_part_tests() { uri.parse("foo://example.com?name=ferret") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), host: Some("example.com"), query: Some("name=ferret"), @@ -387,7 +328,7 @@ pub fn parse_query_part_tests() { uri.parse("foo://example.com/?name=ferret") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), host: Some("example.com"), path: "/", @@ -396,33 +337,25 @@ pub fn parse_query_part_tests() { )) uri.parse("?name=ferret") - |> should.equal(Ok( - Uri(..types.empty_uri, path: "", query: Some("name=ferret")), - )) + |> should.equal(Ok(Uri(..empty, path: "", query: Some("name=ferret")))) uri.parse("over/there?name=ferret") |> should.equal(Ok( - Uri(..types.empty_uri, path: "over/there", query: Some("name=ferret")), + Uri(..empty, path: "over/there", query: Some("name=ferret")), )) uri.parse("/?name=ferret") - |> should.equal(Ok( - Uri(..types.empty_uri, path: "/", query: Some("name=ferret")), - )) + |> should.equal(Ok(Uri(..empty, path: "/", query: Some("name=ferret")))) uri.parse("/over/there?name=ferret") |> should.equal(Ok( - Uri(..types.empty_uri, path: "/over/there", query: Some("name=ferret")), + Uri(..empty, path: "/over/there", query: Some("name=ferret")), )) uri.parse("//example.com?name=ferret") |> should.equal(Ok( - Uri( - ..types.empty_uri, - host: Some("example.com"), - query: Some("name=ferret"), - ), + Uri(..empty, host: Some("example.com"), query: Some("name=ferret")), )) uri.parse("//example.com/?name=ferret") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, host: Some("example.com"), path: "/", query: Some("name=ferret"), @@ -433,7 +366,7 @@ pub fn parse_query_part_tests() { uri.parse("foo://example.com/?name=%E5%90%88%E6%B0%97%E9%81%93") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), host: Some("example.com"), path: "/", @@ -443,7 +376,7 @@ pub fn parse_query_part_tests() { uri.parse("//example.com/?name=%E5%90%88%E6%B0%97%E9%81%93") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, host: Some("example.com"), path: "/", query: Some("name=%E5%90%88%E6%B0%97%E9%81%93"), @@ -458,12 +391,12 @@ pub fn parse_fragment_tests() { it("simple parse", fn() { uri.parse("foo:#nose") |> should.equal(Ok( - Uri(..types.empty_uri, scheme: Some("foo"), fragment: Some("nose")), + Uri(..empty, scheme: Some("foo"), fragment: Some("nose")), )) uri.parse("foo:over/there#nose") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), path: "over/there", fragment: Some("nose"), @@ -472,7 +405,7 @@ pub fn parse_fragment_tests() { uri.parse("foo:/over/there#nose") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), path: "/over/there", fragment: Some("nose"), @@ -481,7 +414,7 @@ pub fn parse_fragment_tests() { uri.parse("foo://example.com#nose") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), host: Some("example.com"), fragment: Some("nose"), @@ -490,7 +423,7 @@ pub fn parse_fragment_tests() { uri.parse("foo://example.com/#nose") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), host: Some("example.com"), path: "/", @@ -500,7 +433,7 @@ pub fn parse_fragment_tests() { uri.parse("foo://example.com#nose") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), host: Some("example.com"), fragment: Some("nose"), @@ -508,31 +441,25 @@ pub fn parse_fragment_tests() { )) uri.parse("#nose") - |> should.equal(Ok(Uri(..types.empty_uri, fragment: Some("nose")))) + |> should.equal(Ok(Uri(..empty, fragment: Some("nose")))) uri.parse("over/there#nose") |> should.equal(Ok( - Uri(..types.empty_uri, path: "over/there", fragment: Some("nose")), + Uri(..empty, path: "over/there", fragment: Some("nose")), )) uri.parse("/#nose") - |> should.equal(Ok( - Uri(..types.empty_uri, path: "/", fragment: Some("nose")), - )) + |> should.equal(Ok(Uri(..empty, path: "/", fragment: Some("nose")))) uri.parse("/over/there#nose") |> should.equal(Ok( - Uri(..types.empty_uri, path: "/over/there", fragment: Some("nose")), + Uri(..empty, path: "/over/there", fragment: Some("nose")), )) uri.parse("//example.com#nose") |> should.equal(Ok( - Uri( - ..types.empty_uri, - host: Some("example.com"), - fragment: Some("nose"), - ), + Uri(..empty, host: Some("example.com"), fragment: Some("nose")), )) uri.parse("//example.com/#nose") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, host: Some("example.com"), path: "/", fragment: Some("nose"), @@ -543,7 +470,7 @@ pub fn parse_fragment_tests() { uri.parse("foo://example.com#%E5%90%88%E6%B0%97%E9%81%93") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), host: Some("example.com"), fragment: Some("%E5%90%88%E6%B0%97%E9%81%93"), @@ -552,7 +479,7 @@ pub fn parse_fragment_tests() { uri.parse("//example.com/#%E5%90%88%E6%B0%97%E9%81%93") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, host: Some("example.com"), path: "/", fragment: Some("%E5%90%88%E6%B0%97%E9%81%93"), @@ -566,44 +493,25 @@ pub fn parse_special_tests() { describe("special parsing", [ it("special 1", fn() { uri.parse("//?") - |> should.equal(Ok( - Uri(..types.empty_uri, host: Some(""), query: Some("")), - )) + |> should.equal(Ok(Uri(..empty, host: Some(""), query: Some("")))) uri.parse("//#") - |> should.equal(Ok( - Uri(..types.empty_uri, host: Some(""), fragment: Some("")), - )) + |> should.equal(Ok(Uri(..empty, host: Some(""), fragment: Some("")))) uri.parse("//?#") |> should.equal(Ok( - Uri( - ..types.empty_uri, - host: Some(""), - query: Some(""), - fragment: Some(""), - ), + Uri(..empty, host: Some(""), query: Some(""), fragment: Some("")), )) uri.parse("foo://?") |> should.equal(Ok( - Uri( - ..types.empty_uri, - scheme: Some("foo"), - host: Some(""), - query: Some(""), - ), + Uri(..empty, scheme: Some("foo"), host: Some(""), query: Some("")), )) uri.parse("foo://#") |> should.equal(Ok( - Uri( - ..types.empty_uri, - scheme: Some("foo"), - host: Some(""), - fragment: Some(""), - ), + Uri(..empty, scheme: Some("foo"), host: Some(""), fragment: Some("")), )) uri.parse("foo://?#") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), host: Some(""), query: Some(""), @@ -611,23 +519,21 @@ pub fn parse_special_tests() { ), )) uri.parse("///") - |> should.equal(Ok(Uri(..types.empty_uri, host: Some(""), path: "/"))) + |> should.equal(Ok(Uri(..empty, host: Some(""), path: "/"))) uri.parse("///hostname") - |> should.equal(Ok( - Uri(..types.empty_uri, host: Some(""), path: "/hostname"), - )) + |> should.equal(Ok(Uri(..empty, host: Some(""), path: "/hostname"))) uri.parse("///?") |> should.equal(Ok( - Uri(..types.empty_uri, host: Some(""), path: "/", query: Some("")), + Uri(..empty, host: Some(""), path: "/", query: Some("")), )) uri.parse("///#") |> should.equal(Ok( - Uri(..types.empty_uri, host: Some(""), path: "/", fragment: Some("")), + Uri(..empty, host: Some(""), path: "/", fragment: Some("")), )) uri.parse("///?#") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, host: Some(""), path: "/", query: Some(""), @@ -635,37 +541,23 @@ pub fn parse_special_tests() { ), )) uri.parse("//foo?") - |> should.equal(Ok( - Uri(..types.empty_uri, host: Some("foo"), query: Some("")), - )) + |> should.equal(Ok(Uri(..empty, host: Some("foo"), query: Some("")))) uri.parse("//foo#") - |> should.equal(Ok( - Uri(..types.empty_uri, host: Some("foo"), fragment: Some("")), - )) + |> should.equal(Ok(Uri(..empty, host: Some("foo"), fragment: Some("")))) uri.parse("//foo?#") |> should.equal(Ok( - Uri( - ..types.empty_uri, - host: Some("foo"), - query: Some(""), - fragment: Some(""), - ), + Uri(..empty, host: Some("foo"), query: Some(""), fragment: Some("")), )) uri.parse("//foo/") - |> should.equal(Ok(Uri(..types.empty_uri, host: Some("foo"), path: "/"))) + |> should.equal(Ok(Uri(..empty, host: Some("foo"), path: "/"))) uri.parse("http://foo?") |> should.equal(Ok( - Uri( - ..types.empty_uri, - scheme: Some("http"), - host: Some("foo"), - query: Some(""), - ), + Uri(..empty, scheme: Some("http"), host: Some("foo"), query: Some("")), )) uri.parse("http://foo#") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("http"), host: Some("foo"), fragment: Some(""), @@ -674,7 +566,7 @@ pub fn parse_special_tests() { uri.parse("http://foo?#") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("http"), host: Some("foo"), query: Some(""), @@ -683,17 +575,12 @@ pub fn parse_special_tests() { )) uri.parse("http://foo/") |> should.equal(Ok( - Uri( - ..types.empty_uri, - scheme: Some("http"), - host: Some("foo"), - path: "/", - ), + Uri(..empty, scheme: Some("http"), host: Some("foo"), path: "/"), )) uri.parse("http://foo:80?") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("http"), host: Some("foo"), port: Some(80), @@ -703,7 +590,7 @@ pub fn parse_special_tests() { uri.parse("http://foo:80#") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("http"), host: Some("foo"), port: Some(80), @@ -713,7 +600,7 @@ pub fn parse_special_tests() { uri.parse("http://foo:80?#") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("http"), host: Some("foo"), port: Some(80), @@ -724,7 +611,7 @@ pub fn parse_special_tests() { uri.parse("http://foo:80/") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("http"), host: Some("foo"), port: Some(80), @@ -732,13 +619,13 @@ pub fn parse_special_tests() { ), )) uri.parse("?") - |> should.equal(Ok(Uri(..types.empty_uri, path: "", query: Some("")))) + |> should.equal(Ok(Uri(..empty, path: "", query: Some("")))) uri.parse("??") - |> should.equal(Ok(Uri(..types.empty_uri, path: "", query: Some("?")))) + |> should.equal(Ok(Uri(..empty, path: "", query: Some("?")))) uri.parse("???") - |> should.equal(Ok(Uri(..types.empty_uri, path: "", query: Some("??")))) + |> should.equal(Ok(Uri(..empty, path: "", query: Some("??")))) uri.parse("#") - |> should.equal(Ok(Uri(..types.empty_uri, path: "", fragment: Some("")))) + |> should.equal(Ok(Uri(..empty, path: "", fragment: Some("")))) uri.parse("##") |> should.be_error uri.parse("###") @@ -748,7 +635,7 @@ pub fn parse_special_tests() { uri.parse("a://:1/") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("a"), host: Some(""), port: Some(1), @@ -756,15 +643,15 @@ pub fn parse_special_tests() { ), )) uri.parse("a:/a/") - |> should.equal(Ok(Uri(..types.empty_uri, scheme: Some("a"), path: "/a/"))) + |> should.equal(Ok(Uri(..empty, scheme: Some("a"), path: "/a/"))) uri.parse("//@") |> should.equal(Ok( - Uri(..types.empty_uri, host: Some(""), path: "", userinfo: Some("")), + Uri(..empty, host: Some(""), path: "", userinfo: Some("")), )) uri.parse("foo://@") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), host: Some(""), path: "", @@ -773,12 +660,12 @@ pub fn parse_special_tests() { )) uri.parse("//@/") |> should.equal(Ok( - Uri(..types.empty_uri, host: Some(""), path: "/", userinfo: Some("")), + Uri(..empty, host: Some(""), path: "/", userinfo: Some("")), )) uri.parse("foo://@/") |> should.equal(Ok( Uri( - ..types.empty_uri, + ..empty, scheme: Some("foo"), host: Some(""), path: "/", @@ -786,11 +673,9 @@ pub fn parse_special_tests() { ), )) uri.parse("//localhost:/") - |> should.equal(Ok( - Uri(..types.empty_uri, host: Some("localhost"), path: "/"), - )) + |> should.equal(Ok(Uri(..empty, host: Some("localhost"), path: "/"))) uri.parse("//:") - |> should.equal(Ok(Uri(..types.empty_uri, host: Some(""), path: ""))) + |> should.equal(Ok(Uri(..empty, host: Some(""), path: ""))) }), ]) } @@ -1000,11 +885,11 @@ pub fn normalise_tests() { uri.parse("/a/b/c/./../../g") |> should.be_ok |> uri.normalise - |> should.equal(Uri(..empty_uri, path: "/a/g")) + |> should.equal(Uri(..empty, path: "/a/g")) uri.parse("mid/content=5/../6") |> should.be_ok |> uri.normalise - |> should.equal(Uri(..empty_uri, path: "mid/6")) + |> should.equal(Uri(..empty, path: "mid/6")) }), it("normalise ports", fn() { uri.parse("http://example.com:80/test") @@ -1012,7 +897,7 @@ pub fn normalise_tests() { |> uri.normalise |> should.equal( Uri( - ..empty_uri, + ..empty, scheme: Some("http"), host: Some("example.com"), path: "/test", @@ -1023,7 +908,7 @@ pub fn normalise_tests() { |> uri.normalise |> should.equal( Uri( - ..empty_uri, + ..empty, scheme: Some("https"), host: Some("example.com"), path: "/test", @@ -1034,7 +919,7 @@ pub fn normalise_tests() { |> uri.normalise |> should.equal( Uri( - ..empty_uri, + ..empty, scheme: Some("http"), host: Some("example.com"), port: Some(8080), @@ -1046,7 +931,7 @@ pub fn normalise_tests() { |> uri.normalise |> should.equal( Uri( - ..empty_uri, + ..empty, scheme: Some("https"), host: Some("example.com"), port: Some(8043), @@ -1146,7 +1031,7 @@ pub fn to_string_tests() { describe("to_string test", [ it("simple test", fn() { let test_uri = - types.Uri( + Uri( Some("https"), Some("weebl:bob"), Some("example.com"), @@ -1161,16 +1046,16 @@ pub fn to_string_tests() { ) }), it("path only", fn() { - types.Uri(..types.empty_uri, path: "/") + Uri(..empty, path: "/") |> uri.to_string |> should.equal("/") - types.Uri(..types.empty_uri, path: "/blah") + Uri(..empty, path: "/blah") |> uri.to_string |> should.equal("/blah") - types.Uri(..types.empty_uri, userinfo: Some("user"), path: "/blah") + Uri(..empty, userinfo: Some("user"), path: "/blah") |> uri.to_string |> should.equal("/blah") - types.Uri(..types.empty_uri, path: "") + Uri(..empty, path: "") |> uri.to_string |> should.equal("") }), diff --git a/uri.abnf b/uri.abnf new file mode 100644 index 0000000..5cec2fc --- /dev/null +++ b/uri.abnf @@ -0,0 +1,94 @@ +URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] + + hier-part = "//" authority path-abempty + / path-absolute + / path-rootless + / path-empty + + URI-reference = URI / relative-ref + + absolute-URI = scheme ":" hier-part [ "?" query ] + + relative-ref = relative-part [ "?" query ] [ "#" fragment ] + + relative-part = "//" authority path-abempty + / path-absolute + / path-noscheme + / path-empty + + scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + + authority = [ userinfo "@" ] host [ ":" port ] + userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) + host = IP-literal / IPv4address / reg-name + port = *DIGIT + + IP-literal = "[" ( IPv6address / IPvFuture ) "]" + + IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) + + IPv6address = 6( h16 ":" ) ls32 + / "::" 5( h16 ":" ) ls32 + / [ h16 ] "::" 4( h16 ":" ) ls32 + / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 + / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 + / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 + / [ *4( h16 ":" ) h16 ] "::" ls32 + / [ *5( h16 ":" ) h16 ] "::" h16 + / [ *6( h16 ":" ) h16 ] "::" + + h16 = 1*4HEXDIG + ls32 = ( h16 ":" h16 ) / IPv4address + IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet + + + + + + + +Berners-Lee, et al. Standards Track [Page 49] + +RFC 3986 URI Generic Syntax January 2005 + + + dec-octet = DIGIT ; 0-9 + / %x31-39 DIGIT ; 10-99 + / "1" 2DIGIT ; 100-199 + / "2" %x30-34 DIGIT ; 200-249 + / "25" %x30-35 ; 250-255 + + reg-name = *( unreserved / pct-encoded / sub-delims ) + + path = path-abempty ; begins with "/" or is empty + / path-absolute ; begins with "/" but not "//" + / path-noscheme ; begins with a non-colon segment + / path-rootless ; begins with a segment + / path-empty ; zero characters + + path-abempty = *( "/" segment ) + path-absolute = "/" [ segment-nz *( "/" segment ) ] + path-noscheme = segment-nz-nc *( "/" segment ) + path-rootless = segment-nz *( "/" segment ) + path-empty = 0 + + segment = *pchar + segment-nz = 1*pchar + segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) + ; non-zero-length segment without any colon ":" + + pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + + query = *( pchar / "/" / "?" ) + + fragment = *( pchar / "/" / "?" ) + + pct-encoded = "%" HEXDIG HEXDIG + + unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + reserved = gen-delims / sub-delims + gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" + sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + / "*" / "+" / "," / ";" / "=" + + " # % < > [ \ ] ^ ` { | } \ No newline at end of file