1pub mod uri;
2
3#[derive(Debug, Clone, Copy)]
4pub enum ParseRIError {
5 InvalidAuthority,
6 InvalidPathAbsolute,
7 InvalidSegmentNzNc,
8 InvalidPChar,
9 InvalidScheme,
10 InvalidSchemeSeparator,
11 InvalidIPLiteral,
12 InvalidIPvFuture,
13 InvalidIPv6address,
14 InvalidH16,
15 InvalidLS32,
16 InvalidIPv4address,
17 InvalidDecOctet,
18 InvalidPctEncoded,
19 NotTermination,
20 Unsupported,
21 Unknown,
22}
23
24#[cfg(test)]
25mod tests {
26 use crate::uri::URIString;
27
28 #[test]
32 fn uri_parse_tests() {
33 let uri = URIString::parse(r#"ftp://ftp.is.co.za/rfc/rfc1808.txt"#).unwrap();
34 assert_eq!(uri.scheme().unwrap(), "ftp");
35 assert_eq!(uri.authority().unwrap(), "ftp.is.co.za");
36 assert!(uri.userinfo().is_none());
37 assert_eq!(uri.host().unwrap(), "ftp.is.co.za");
38 assert!(uri.port().is_none());
39 assert_eq!(uri.path(), "/rfc/rfc1808.txt");
40 assert!(uri.query().is_none());
41 assert!(uri.fragment().is_none());
42
43 let uri = URIString::parse(r#"http://www.ietf.org/rfc/rfc2396.txt"#).unwrap();
44 assert_eq!(uri.scheme().unwrap(), "http");
45 assert_eq!(uri.authority().unwrap(), "www.ietf.org");
46 assert!(uri.userinfo().is_none());
47 assert_eq!(uri.host().unwrap(), "www.ietf.org");
48 assert!(uri.port().is_none());
49 assert_eq!(uri.path(), "/rfc/rfc2396.txt");
50 assert!(uri.query().is_none());
51 assert!(uri.fragment().is_none());
52
53 let uri = URIString::parse(r#"ldap://[2001:db8::7]/c=GB?objectClass?one"#).unwrap();
54 assert_eq!(uri.scheme().unwrap(), "ldap");
55 assert_eq!(uri.authority().unwrap(), "[2001:db8::7]");
56 assert!(uri.userinfo().is_none());
57 assert_eq!(uri.host().unwrap(), "[2001:db8::7]");
58 assert!(uri.port().is_none());
59 assert_eq!(uri.path(), "/c=GB");
60 assert_eq!(uri.query().unwrap(), "objectClass?one");
61 assert!(uri.fragment().is_none());
62
63 let uri = URIString::parse(r#"mailto:John.Doe@example.com"#).unwrap();
64 assert_eq!(uri.scheme().unwrap(), "mailto");
65 assert!(uri.authority().is_none());
66 assert!(uri.userinfo().is_none());
67 assert!(uri.host().is_none());
68 assert!(uri.port().is_none());
69 assert_eq!(uri.path(), "John.Doe@example.com");
70 assert!(uri.query().is_none());
71 assert!(uri.fragment().is_none());
72
73 let uri = URIString::parse(r#"news:comp.infosystems.www.servers.unix"#).unwrap();
74 assert_eq!(uri.scheme().unwrap(), "news");
75 assert!(uri.authority().is_none());
76 assert!(uri.userinfo().is_none());
77 assert!(uri.host().is_none());
78 assert!(uri.port().is_none());
79 assert_eq!(uri.path(), "comp.infosystems.www.servers.unix");
80 assert!(uri.query().is_none());
81 assert!(uri.fragment().is_none());
82
83 let uri = URIString::parse(r#"tel:+1-816-555-1212"#).unwrap();
84 assert_eq!(uri.scheme().unwrap(), "tel");
85 assert!(uri.authority().is_none());
86 assert!(uri.userinfo().is_none());
87 assert!(uri.host().is_none());
88 assert!(uri.port().is_none());
89 assert_eq!(uri.path(), "+1-816-555-1212");
90 assert!(uri.query().is_none());
91 assert!(uri.fragment().is_none());
92
93 let uri = URIString::parse(r#"telnet://192.0.2.16:80/"#).unwrap();
94 assert_eq!(uri.scheme().unwrap(), "telnet");
95 assert_eq!(uri.authority().unwrap(), "192.0.2.16:80");
96 assert!(uri.userinfo().is_none());
97 assert_eq!(uri.host().unwrap(), "192.0.2.16");
98 assert_eq!(uri.port().unwrap(), "80");
99 assert_eq!(uri.path(), "/");
100 assert!(uri.query().is_none());
101 assert!(uri.fragment().is_none());
102
103 let uri =
104 URIString::parse(r#"urn:oasis:names:specification:docbook:dtd:xml:4.1.2"#).unwrap();
105 assert_eq!(uri.scheme().unwrap(), "urn");
106 assert!(uri.authority().is_none());
107 assert!(uri.userinfo().is_none());
108 assert!(uri.host().is_none());
109 assert!(uri.port().is_none());
110 assert_eq!(
111 uri.path(),
112 "oasis:names:specification:docbook:dtd:xml:4.1.2"
113 );
114 assert!(uri.query().is_none());
115 assert!(uri.fragment().is_none());
116
117 let uri =
118 URIString::parse(r#"foo://example.com:8042/over/there?name=ferret#nose"#).unwrap();
119 assert_eq!(uri.scheme().unwrap(), "foo");
120 assert_eq!(uri.authority().unwrap(), "example.com:8042");
121 assert!(uri.userinfo().is_none());
122 assert_eq!(uri.host().unwrap(), "example.com");
123 assert_eq!(uri.port().unwrap(), "8042");
124 assert_eq!(uri.path(), "/over/there");
125 assert_eq!(uri.query().unwrap(), "name=ferret");
126 assert_eq!(uri.fragment().unwrap(), "nose");
127
128 let uri = URIString::parse(r#"foo:"#).unwrap();
130 assert_eq!(uri.scheme().unwrap(), "foo");
131 assert!(uri.authority().is_none());
132 assert!(uri.userinfo().is_none());
133 assert!(uri.host().is_none());
134 assert!(uri.port().is_none());
135 assert_eq!(uri.path(), "");
136 assert!(uri.query().is_none());
137 assert!(uri.fragment().is_none());
138
139 let uri = URIString::parse(r#"foo:/"#).unwrap();
140 assert_eq!(uri.scheme().unwrap(), "foo");
141 assert!(uri.authority().is_none());
142 assert!(uri.userinfo().is_none());
143 assert!(uri.host().is_none());
144 assert!(uri.port().is_none());
145 assert_eq!(uri.path(), "/");
146 assert!(uri.query().is_none());
147 assert!(uri.fragment().is_none());
148
149 let uri = URIString::parse(r#"foo://"#).unwrap();
150 assert_eq!(uri.scheme().unwrap(), "foo");
151 assert_eq!(uri.authority().unwrap(), "");
152 assert!(uri.userinfo().is_none());
153 assert_eq!(uri.host().unwrap(), "");
154 assert!(uri.port().is_none());
155 assert_eq!(uri.path(), "");
156 assert!(uri.query().is_none());
157 assert!(uri.fragment().is_none());
158
159 let uri = URIString::parse(r#"foo:///"#).unwrap();
160 assert_eq!(uri.scheme().unwrap(), "foo");
161 assert_eq!(uri.authority().unwrap(), "");
162 assert!(uri.userinfo().is_none());
163 assert_eq!(uri.host().unwrap(), "");
164 assert!(uri.port().is_none());
165 assert_eq!(uri.path(), "/");
166 assert!(uri.query().is_none());
167 assert!(uri.fragment().is_none());
168
169 let uri = URIString::parse(r#"foo:////"#).unwrap();
170 assert_eq!(uri.scheme().unwrap(), "foo");
171 assert_eq!(uri.authority().unwrap(), "");
172 assert!(uri.userinfo().is_none());
173 assert_eq!(uri.host().unwrap(), "");
174 assert!(uri.port().is_none());
175 assert_eq!(uri.path(), "//");
176 assert!(uri.query().is_none());
177 assert!(uri.fragment().is_none());
178 }
179
180 #[test]
182 fn uri_resolve_tests() {
183 let base = URIString::parse(r#"http://a/b/c/d;p?q"#).unwrap();
184 assert!(base.is_absolute());
185
186 let rel = URIString::parse("g:h").unwrap();
188 assert_eq!(base.resolve(&rel).as_escaped_str(), "g:h");
189 let rel = URIString::parse("g").unwrap();
190 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g");
191 let rel = URIString::parse("./g").unwrap();
192 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g");
193 let rel = URIString::parse("g/").unwrap();
194 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g/");
195 let rel = URIString::parse("/g").unwrap();
196 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/g");
197 let rel = URIString::parse("//g").unwrap();
198 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://g");
199 let rel = URIString::parse("?y").unwrap();
200 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/d;p?y");
201 let rel = URIString::parse("g?y").unwrap();
202 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g?y");
203 let rel = URIString::parse("#s").unwrap();
204 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/d;p?q#s");
205 let rel = URIString::parse("g#s").unwrap();
206 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g#s");
207 let rel = URIString::parse("g?y#s").unwrap();
208 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g?y#s");
209 let rel = URIString::parse(";x").unwrap();
210 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/;x");
211 let rel = URIString::parse("g;x").unwrap();
212 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g;x");
213 let rel = URIString::parse("g;x?y#s").unwrap();
214 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g;x?y#s");
215 let rel = URIString::parse("").unwrap();
216 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/d;p?q");
217 let rel = URIString::parse(".").unwrap();
218 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/");
219 let rel = URIString::parse("./").unwrap();
220 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/");
221 let rel = URIString::parse("..").unwrap();
222 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/");
223 let rel = URIString::parse("../").unwrap();
224 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/");
225 let rel = URIString::parse("../g").unwrap();
226 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/g");
227 let rel = URIString::parse("../..").unwrap();
228 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/");
229 let rel = URIString::parse("../../").unwrap();
230 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/");
231 let rel = URIString::parse("../../g").unwrap();
232 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/g");
233
234 let rel = URIString::parse("../../../g").unwrap();
236 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/g");
237 let rel = URIString::parse("../../../../g").unwrap();
238 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/g");
239 let rel = URIString::parse("/./g").unwrap();
240 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/g");
241 let rel = URIString::parse("/../g").unwrap();
242 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/g");
243 let rel = URIString::parse("g.").unwrap();
244 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g.");
245 let rel = URIString::parse(".g").unwrap();
246 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/.g");
247 let rel = URIString::parse("g..").unwrap();
248 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g..");
249 let rel = URIString::parse("..g").unwrap();
250 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/..g");
251 let rel = URIString::parse("./../g").unwrap();
252 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/g");
253 let rel = URIString::parse("./g/.").unwrap();
254 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g/");
255 let rel = URIString::parse("g/./h").unwrap();
256 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g/h");
257 let rel = URIString::parse("g/../h").unwrap();
258 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/h");
259 let rel = URIString::parse("g;x=1/./y").unwrap();
260 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g;x=1/y");
261 let rel = URIString::parse("g;x=1/../y").unwrap();
262 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/y");
263 let rel = URIString::parse("g?y/./x").unwrap();
264 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g?y/./x");
265 let rel = URIString::parse("g?y/../x").unwrap();
266 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g?y/../x");
267 let rel = URIString::parse("g#s/./x").unwrap();
268 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g#s/./x");
269 let rel = URIString::parse("g#s/../x").unwrap();
270 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g#s/../x");
271
272 assert_eq!(
274 URIString::parse("http://www.example.org/one/two")
275 .unwrap()
276 .resolve(&URIString::parse("").unwrap())
277 .as_escaped_str(),
278 "http://www.example.org/one/two"
279 );
280 assert_eq!(
281 URIString::parse("http://www.example.org/one/two#frag")
282 .unwrap()
283 .resolve(&URIString::parse("").unwrap())
284 .as_escaped_str(),
285 "http://www.example.org/one/two"
286 );
287 }
288
289 #[cfg(target_family = "windows")]
290 #[test]
291 fn windows_path_test() {
292 assert_eq!(
293 URIString::parse_file_path("C:\\Windows\\System32\\")
294 .unwrap()
295 .as_escaped_str(),
296 "file:C:/Windows/System32/"
297 );
298 assert_eq!(
299 URIString::parse_file_path("\\\\localhost\\share\\")
300 .unwrap()
301 .as_escaped_str(),
302 "file://localhost/share/"
303 );
304 }
305}