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