1#![doc(html_root_url = "https://docs.rs/parse-dat-url/0.1.0/")]
2#![deny(missing_docs)]
3
4use core::fmt;
15use core::str::FromStr;
16use lazy_static::lazy_static;
17use regex::Regex;
18use std::borrow::Cow;
19use url::Url;
20
21#[cfg(feature = "serde")]
22mod serde;
23
24lazy_static! {
25 static ref VERSION_REGEX: Regex = Regex::new(
26 r#"(?i)^(?P<scheme>\w+://)?(?P<hostname>[^/+]+)(\+(?P<version>[^/]+))?(?P<path>.*)$"#
27 )
28 .expect("Version regex not valid");
29}
30
31#[derive(Debug, Eq, PartialEq)]
33pub enum Error {
34 InvalidRegex,
36 InvalidUrl(url::ParseError),
39 MissingHostname,
41}
42
43impl fmt::Display for Error {
44 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
45 match self {
46 Error::InvalidRegex => write!(f, "regex defined on library can't match the value")?,
47 Error::InvalidUrl(_) => write!(f, "malformed url not conforming to URL Spec")?,
48 Error::MissingHostname => write!(f, "missing hostname on url")?,
49 };
50 Ok(())
51 }
52}
53
54impl std::error::Error for Error {}
55
56#[derive(Debug, Eq, PartialEq, Clone)]
71pub struct DatUrl<'a> {
72 scheme: Cow<'a, str>,
73 host: Cow<'a, str>,
74 version: Option<Cow<'a, str>>,
75 path: Option<Cow<'a, str>>,
76 url: Url,
77}
78
79impl<'a> fmt::Display for DatUrl<'a> {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 write!(f, "{}{}", self.scheme, self.host,)?;
82 if let Some(version) = &self.version {
83 write!(f, "+{}", version)?;
84 }
85 if let Some(path) = &self.path {
86 write!(f, "{}", path)?;
87 }
88 Ok(())
89 }
90}
91
92impl<'a> DatUrl<'a> {
93 fn url_str(scheme: &str, host: &str, path: &Option<&str>) -> String {
94 format!("{}{}{}", scheme, host, path.map_or("", |path| &path))
95 }
96
97 pub fn parse(url: &str) -> Result<DatUrl, Error> {
101 let capture = VERSION_REGEX.captures(url).ok_or(Error::InvalidRegex)?;
102
103 let version = capture.name("version").map(|c| c.as_str());
104
105 let host = capture
106 .name("hostname")
107 .ok_or(Error::MissingHostname)?
108 .as_str();
109
110 let path = capture.name("path").and_then(|c| match c.as_str() {
111 "" => None,
112 s => Some(s),
113 });
114
115 let scheme = capture
116 .name("scheme")
117 .map(|c| c.as_str())
118 .unwrap_or("dat://");
119
120 let valid_url = Url::parse(&DatUrl::url_str(&scheme, &host, &path))
121 .map_err(|e| Error::InvalidUrl(e))?;
122
123 Ok(DatUrl {
124 version: version.map(Cow::from),
125 host: host.into(),
126 path: path.map(Cow::from),
127 scheme: scheme.into(),
128 url: valid_url,
129 })
130 }
131
132 pub fn into_owned(self) -> DatUrl<'static> {
151 DatUrl {
152 host: self.host.to_owned().into_owned().into(),
153 scheme: self.scheme.to_owned().into_owned().into(),
154 version: self.version.to_owned().map(|v| v.into_owned().into()),
155 path: self.path.to_owned().map(|p| p.into_owned().into()),
156 url: self.url,
157 }
158 }
159
160 #[inline]
162 pub fn scheme(&self) -> &Cow<str> {
163 &self.scheme
164 }
165
166 #[inline]
168 pub fn host(&self) -> &Cow<str> {
169 &self.host
170 }
171
172 #[inline]
174 pub fn version(&self) -> &Option<Cow<str>> {
175 &self.version
176 }
177
178 #[inline]
180 pub fn path(&self) -> &Option<Cow<str>> {
181 &self.path
182 }
183}
184
185impl<'a> FromStr for DatUrl<'a> {
186 type Err = Error;
187
188 fn from_str(s: &str) -> Result<Self, Self::Err> {
189 DatUrl::parse(s).map(DatUrl::into_owned)
190 }
191}
192
193impl<'a> std::convert::TryFrom<&'a str> for DatUrl<'a> {
194 type Error = Error;
195
196 #[inline]
197 fn try_from(s: &'a str) -> Result<Self, Self::Error> {
198 DatUrl::parse(s)
199 }
200}
201
202impl<'a> AsRef<Url> for DatUrl<'a> {
203 #[inline]
204 fn as_ref(&self) -> &Url {
205 &self.url
206 }
207}
208
209impl<'a> From<DatUrl<'a>> for Url {
210 #[inline]
211 fn from(dat_url: DatUrl<'a>) -> Self {
212 dat_url.url
213 }
214}
215
216#[cfg(test)]
217mod tests {
218 use pretty_assertions::assert_eq;
219
220 use super::DatUrl;
221 use url::Url;
222
223 #[test]
224 fn it_parses_the_urls() {
225 let inputs: &str =
226 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+0.0.0.1/
227dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+1/
228dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+c1/
229dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1/
230dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1.0.0/
231dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+latest/
232dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+0.0.0.1/path/to+file.txt
233dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+1/path/to+file.txt
234dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+c1/path/to+file.txt
235dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1/path/to+file.txt
236dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1.0.0/path/to+file.txt
237dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+latest/path/to+file.txt
238dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+0.0.0.1
239dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+1
240dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+c1
241dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1
242dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1.0.0
243dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+latest
244dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/
245dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt
246dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21
247584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+0.0.0.1/
248584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+1/
249584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+c1/
250584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1/
251584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1.0.0/
252584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+latest/
253584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+0.0.0.1/path/to+file.txt
254584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+1/path/to+file.txt
255584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+c1/path/to+file.txt
256584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1/path/to+file.txt
257584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1.0.0/path/to+file.txt
258584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+latest/path/to+file.txt
259584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+0.0.0.1
260584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+1
261584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+c1
262584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1
263584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1.0.0
264584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+latest
265584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/
266584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21
267584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt
268dat://example.com+0.0.0.1/
269dat://example.com+1/
270dat://example.com+c1/
271dat://example.com+v1/
272dat://example.com+v1.0.0/
273dat://example.com+latest/
274dat://example.com+0.0.0.1/path/to+file.txt
275dat://example.com+1/path/to+file.txt
276dat://example.com+c1/path/to+file.txt
277dat://example.com+v1/path/to+file.txt
278dat://example.com+v1.0.0/path/to+file.txt
279dat://example.com+latest/path/to+file.txt
280dat://example.com+0.0.0.1
281dat://example.com+1
282dat://example.com+c1
283dat://example.com+v1
284dat://example.com+v1.0.0
285dat://example.com+latest
286dat://example.com/
287dat://example.com
288dat://example.com/path/to+file.txt
289example.com+0.0.0.1/
290example.com+1/
291example.com+c1/
292example.com+v1/
293example.com+v1.0.0/
294example.com+latest/
295example.com+0.0.0.1/path/to+file.txt
296example.com+1/path/to+file.txt
297example.com+c1/path/to+file.txt
298example.com+v1/path/to+file.txt
299example.com+v1.0.0/path/to+file.txt
300example.com+latest/path/to+file.txt
301example.com+0.0.0.1
302example.com+1
303example.com+c1
304example.com+v1
305example.com+v1.0.0
306example.com+latest
307example.com/
308example.com
309example.com/path/to+file.txt
310192.0.2.0
311192.0.2.0+v1
312192.0.2.0+0.0.0.1/path/to+file.txt
313192.0.2.0/path/to+file.txt
314[2001:DB8::0]
315[2001:DB8::0]+0.0.0.1/path/to+file.txt";
316
317 let outputs: &[DatUrl] = &[
318 DatUrl {
319 version: Some("0.0.0.1".into()),
320 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
321 path: Some("/".into()),
322 scheme: "dat://".into(),
323 url: Url::parse(
324 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21",
325 )
326 .expect("Invalid test data"),
327 },
328 DatUrl {
329 version: Some("1".into()),
330 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
331 path: Some("/".into()),
332 scheme: "dat://".into(),
333 url: Url::parse(
334 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21",
335 )
336 .expect("Invalid test data"),
337 },
338 DatUrl {
339 version: Some("c1".into()),
340 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
341 path: Some("/".into()),
342 scheme: "dat://".into(),
343 url: Url::parse(
344 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21",
345 )
346 .expect("Invalid test data"),
347 },
348 DatUrl {
349 version: Some("v1".into()),
350 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
351 path: Some("/".into()),
352 scheme: "dat://".into(),
353 url: Url::parse(
354 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21",
355 )
356 .expect("Invalid test data"),
357 },
358 DatUrl {
359 version: Some("v1.0.0".into()),
360 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
361 path: Some("/".into()),
362 scheme: "dat://".into(),
363 url: Url::parse(
364 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21",
365 )
366 .expect("Invalid test data"),
367 },
368 DatUrl {
369 version: Some("latest".into()),
370 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
371 path: Some("/".into()),
372 scheme: "dat://".into(),
373 url: Url::parse(
374 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21",
375 )
376 .expect("Invalid test data"),
377 },
378 DatUrl {
379 version: Some("0.0.0.1".into()),
380 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
381 path: Some("/path/to+file.txt".into()),
382 scheme: "dat://".into(),
383 url: Url::parse(
384 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt",
385 )
386 .expect("Invalid test data"),
387 },
388 DatUrl {
389 version: Some("1".into()),
390 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
391 path: Some("/path/to+file.txt".into()),
392 scheme: "dat://".into(),
393 url: Url::parse(
394 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt",
395 )
396 .expect("Invalid test data"),
397 },
398 DatUrl {
399 version: Some("c1".into()),
400 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
401 path: Some("/path/to+file.txt".into()),
402 scheme: "dat://".into(),
403 url: Url::parse(
404 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt",
405 )
406 .expect("Invalid test data"),
407 },
408 DatUrl {
409 version: Some("v1".into()),
410 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
411 path: Some("/path/to+file.txt".into()),
412 scheme: "dat://".into(),
413 url: Url::parse(
414 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt",
415 )
416 .expect("Invalid test data"),
417 },
418 DatUrl {
419 version: Some("v1.0.0".into()),
420 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
421 path: Some("/path/to+file.txt".into()),
422 scheme: "dat://".into(),
423 url: Url::parse(
424 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt",
425 )
426 .expect("Invalid test data"),
427 },
428 DatUrl {
429 version: Some("latest".into()),
430 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
431 path: Some("/path/to+file.txt".into()),
432 scheme: "dat://".into(),
433 url: Url::parse(
434 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt",
435 )
436 .expect("Invalid test data"),
437 },
438 DatUrl {
439 version: Some("0.0.0.1".into()),
440 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
441 path: None,
442 scheme: "dat://".into(),
443 url: Url::parse(
444 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/",
445 )
446 .expect("Invalid test data"),
447 },
448 DatUrl {
449 version: Some("1".into()),
450 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
451 path: None,
452 scheme: "dat://".into(),
453 url: Url::parse(
454 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/",
455 )
456 .expect("Invalid test data"),
457 },
458 DatUrl {
459 version: Some("c1".into()),
460 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
461 path: None,
462 scheme: "dat://".into(),
463 url: Url::parse(
464 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/",
465 )
466 .expect("Invalid test data"),
467 },
468 DatUrl {
469 version: Some("v1".into()),
470 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
471 path: None,
472 scheme: "dat://".into(),
473 url: Url::parse(
474 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/",
475 )
476 .expect("Invalid test data"),
477 },
478 DatUrl {
479 version: Some("v1.0.0".into()),
480 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
481 path: None,
482 scheme: "dat://".into(),
483 url: Url::parse(
484 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/",
485 )
486 .expect("Invalid test data"),
487 },
488 DatUrl {
489 version: Some("latest".into()),
490 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
491 path: None,
492 scheme: "dat://".into(),
493 url: Url::parse(
494 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/",
495 )
496 .expect("Invalid test data"),
497 },
498 DatUrl {
499 version: None,
500 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
501 path: Some("/".into()),
502 scheme: "dat://".into(),
503 url: Url::parse(
504 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/",
505 )
506 .expect("Invalid test data"), },
507 DatUrl {
508 version: None,
509 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
510 path: Some("/path/to+file.txt".into()),
511 scheme: "dat://".into(),url: Url::parse(
512 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt",
513 )
514 .expect("Invalid test data"),
515 },
516 DatUrl {
517 version: None,
518 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
519 path: None,
520 scheme: "dat://".into(),
521 url: Url::parse(
522 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/",
523 )
524 .expect("Invalid test data"),
525 },
526 DatUrl {
527 version: Some("0.0.0.1".into()),
528 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
529 path: Some("/".into()),
530 scheme: "dat://".into(),
531 url: Url::parse(
532 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/",
533 )
534 .expect("Invalid test data"),
535 },
536 DatUrl {
537 version: Some("1".into()),
538 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
539 path: Some("/".into()),
540 scheme: "dat://".into(),
541 url: Url::parse(
542 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/",
543 )
544 .expect("Invalid test data"),
545 },
546 DatUrl {
547 version: Some("c1".into()),
548 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
549 path: Some("/".into()),
550 scheme: "dat://".into(),
551 url: Url::parse(
552 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/",
553 )
554 .expect("Invalid test data"),
555 },
556 DatUrl {
557 version: Some("v1".into()),
558 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
559 path: Some("/".into()),
560 scheme: "dat://".into(),
561 url: Url::parse(
562 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/",
563 )
564 .expect("Invalid test data"),
565 },
566 DatUrl {
567 version: Some("v1.0.0".into()),
568 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
569 path: Some("/".into()),
570 scheme: "dat://".into(),
571 url: Url::parse(
572 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/",
573 )
574 .expect("Invalid test data"),
575 },
576 DatUrl {
577 version: Some("latest".into()),
578 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
579 path: Some("/".into()),
580 scheme: "dat://".into(),
581 url: Url::parse(
582 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/",
583 )
584 .expect("Invalid test data"),
585 },
586 DatUrl {
587 version: Some("0.0.0.1".into()),
588 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
589 path: Some("/path/to+file.txt".into()),
590 scheme: "dat://".into(),
591 url: Url::parse(
592 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt",
593 )
594 .expect("Invalid test data"),
595 },
596 DatUrl {
597 version: Some("1".into()),
598 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
599 path: Some("/path/to+file.txt".into()),
600 scheme: "dat://".into(),
601 url: Url::parse(
602 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt",
603 )
604 .expect("Invalid test data"),
605 },
606 DatUrl {
607 version: Some("c1".into()),
608 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
609 path: Some("/path/to+file.txt".into()),
610 scheme: "dat://".into(),
611 url: Url::parse(
612 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt",
613 )
614 .expect("Invalid test data"),
615 },
616 DatUrl {
617 version: Some("v1".into()),
618 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
619 path: Some("/path/to+file.txt".into()),
620 scheme: "dat://".into(),
621 url: Url::parse(
622 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt",
623 )
624 .expect("Invalid test data"),
625 },
626 DatUrl {
627 version: Some("v1.0.0".into()),
628 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
629 path: Some("/path/to+file.txt".into()),
630 scheme: "dat://".into(),
631 url: Url::parse(
632 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt",
633 )
634 .expect("Invalid test data"),
635 },
636 DatUrl {
637 version: Some("latest".into()),
638 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
639 path: Some("/path/to+file.txt".into()),
640 scheme: "dat://".into(),
641 url: Url::parse(
642 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt",
643 )
644 .expect("Invalid test data"),
645 },
646 DatUrl {
647 version: Some("0.0.0.1".into()),
648 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
649 path: None,
650 scheme: "dat://".into(),
651 url: Url::parse(
652 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21",
653 )
654 .expect("Invalid test data"),
655 },
656 DatUrl {
657 version: Some("1".into()),
658 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
659 path: None,
660 scheme: "dat://".into(),
661 url: Url::parse(
662 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21",
663 )
664 .expect("Invalid test data"),
665
666 },
667 DatUrl {
668 version: Some("c1".into()),
669 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
670 path: None,
671 scheme: "dat://".into(),
672 url: Url::parse(
673 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21",
674 )
675 .expect("Invalid test data"),
676
677 },
678 DatUrl {
679 version: Some("v1".into()),
680 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
681 path: None,
682 scheme: "dat://".into(),
683 url: Url::parse(
684 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21",
685 )
686 .expect("Invalid test data"),
687 },
688 DatUrl {
689 version: Some("v1.0.0".into()),
690 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
691 path: None,
692 scheme: "dat://".into(),
693 url: Url::parse(
694 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21",
695 )
696 .expect("Invalid test data"),
697 },
698 DatUrl {
699 version: Some("latest".into()),
700 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
701 path: None,
702 scheme: "dat://".into(),
703 url: Url::parse(
704 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21",
705 )
706 .expect("Invalid test data"),
707 },
708 DatUrl {
709 version: None,
710 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
711 path: Some("/".into()),
712 scheme: "dat://".into(),
713 url: Url::parse(
714 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21",
715 )
716 .expect("Invalid test data"),
717 },
718 DatUrl {
719 version: None,
720 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
721 path: None,
722 scheme: "dat://".into(),
723 url: Url::parse(
724 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21",
725 )
726 .expect("Invalid test data"),
727 },
728 DatUrl {
729 version: None,
730 host: "584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21".into(),
731 path: Some("/path/to+file.txt".into()),
732 scheme: "dat://".into(),
733 url: Url::parse(
734 "dat://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21/path/to+file.txt",
735 )
736 .expect("Invalid test data"),
737 },
738 DatUrl {
739 version: Some("0.0.0.1".into()),
740 host: "example.com".into(),
741 path: Some("/".into()),
742 scheme: "dat://".into(),
743 url: Url::parse(
744 "dat://example.com",
745 )
746 .expect("Invalid test data"),
747 },
748 DatUrl {
749 version: Some("1".into()),
750 host: "example.com".into(),
751 path: Some("/".into()),
752 scheme: "dat://".into(),
753 url: Url::parse(
754 "dat://example.com",
755 )
756 .expect("Invalid test data"),
757 },
758 DatUrl {
759 version: Some("c1".into()),
760 host: "example.com".into(),
761 path: Some("/".into()),
762 scheme: "dat://".into(),
763 url: Url::parse(
764 "dat://example.com",
765 )
766 .expect("Invalid test data"),
767 },
768 DatUrl {
769 version: Some("v1".into()),
770 host: "example.com".into(),
771 path: Some("/".into()),
772 scheme: "dat://".into(),
773 url: Url::parse(
774 "dat://example.com",
775 )
776 .expect("Invalid test data"),
777 },
778 DatUrl {
779 version: Some("v1.0.0".into()),
780 host: "example.com".into(),
781 path: Some("/".into()),
782 scheme: "dat://".into(),
783 url: Url::parse(
784 "dat://example.com",
785 )
786 .expect("Invalid test data"),
787 },
788 DatUrl {
789 version: Some("latest".into()),
790 host: "example.com".into(),
791 path: Some("/".into()),
792 scheme: "dat://".into(),
793 url: Url::parse(
794 "dat://example.com",
795 )
796 .expect("Invalid test data"),
797 },
798 DatUrl {
799 version: Some("0.0.0.1".into()),
800 host: "example.com".into(),
801 path: Some("/path/to+file.txt".into()),
802 scheme: "dat://".into(),
803 url: Url::parse(
804 "dat://example.com/path/to+file.txt",
805 )
806 .expect("Invalid test data"),
807 },
808 DatUrl {
809 version: Some("1".into()),
810 host: "example.com".into(),
811 path: Some("/path/to+file.txt".into()),
812 scheme: "dat://".into(),
813 url: Url::parse(
814 "dat://example.com/path/to+file.txt",
815 )
816 .expect("Invalid test data"),
817
818 },
819 DatUrl {
820 version: Some("c1".into()),
821 host: "example.com".into(),
822 path: Some("/path/to+file.txt".into()),
823 scheme: "dat://".into(),
824 url: Url::parse(
825 "dat://example.com/path/to+file.txt",
826 )
827 .expect("Invalid test data"),
828
829 },
830 DatUrl {
831 version: Some("v1".into()),
832 host: "example.com".into(),
833 path: Some("/path/to+file.txt".into()),
834 scheme: "dat://".into(),
835 url: Url::parse(
836 "dat://example.com/path/to+file.txt",
837 )
838 .expect("Invalid test data"),
839
840 },
841 DatUrl {
842 version: Some("v1.0.0".into()),
843 host: "example.com".into(),
844 path: Some("/path/to+file.txt".into()),
845 scheme: "dat://".into(),
846 url: Url::parse(
847 "dat://example.com/path/to+file.txt",
848 )
849 .expect("Invalid test data"),
850
851 },
852 DatUrl {
853 version: Some("latest".into()),
854 host: "example.com".into(),
855 path: Some("/path/to+file.txt".into()),
856 scheme: "dat://".into(),
857 url: Url::parse(
858 "dat://example.com/path/to+file.txt",
859 )
860 .expect("Invalid test data"),
861
862 },
863 DatUrl {
864 version: Some("0.0.0.1".into()),
865 host: "example.com".into(),
866 path: None,
867 scheme: "dat://".into(),
868 url: Url::parse(
869 "dat://example.com/",
870 )
871 .expect("Invalid test data"),
872
873 },
874 DatUrl {
875 version: Some("1".into()),
876 host: "example.com".into(),
877 path: None,
878 scheme: "dat://".into(),
879 url: Url::parse(
880 "dat://example.com/",
881 )
882 .expect("Invalid test data"),
883
884 },
885 DatUrl {
886 version: Some("c1".into()),
887 host: "example.com".into(),
888 path: None,
889 scheme: "dat://".into(),
890 url: Url::parse(
891 "dat://example.com/",
892 )
893 .expect("Invalid test data"),
894
895 },
896 DatUrl {
897 version: Some("v1".into()),
898 host: "example.com".into(),
899 path: None,
900 scheme: "dat://".into(),
901 url: Url::parse(
902 "dat://example.com/",
903 )
904 .expect("Invalid test data"),
905
906 },
907 DatUrl {
908 version: Some("v1.0.0".into()),
909 host: "example.com".into(),
910 path: None,
911 scheme: "dat://".into(),
912 url: Url::parse(
913 "dat://example.com/",
914 )
915 .expect("Invalid test data"),
916
917 },
918 DatUrl {
919 version: Some("latest".into()),
920 host: "example.com".into(),
921 path: None,
922 scheme: "dat://".into(),
923 url: Url::parse(
924 "dat://example.com/",
925 )
926 .expect("Invalid test data"),
927
928 },
929 DatUrl {
930 version: None,
931 host: "example.com".into(),
932 path: Some("/".into()),
933 scheme: "dat://".into(),
934 url: Url::parse(
935 "dat://example.com/",
936 )
937 .expect("Invalid test data"),
938
939 },
940 DatUrl {
941 version: None,
942 host: "example.com".into(),
943 path: None,
944 scheme: "dat://".into(),
945 url: Url::parse(
946 "dat://example.com/",
947 )
948 .expect("Invalid test data"),
949
950 },
951 DatUrl {
952 version: None,
953 host: "example.com".into(),
954 path: Some("/path/to+file.txt".into()),
955 scheme: "dat://".into(),
956 url: Url::parse(
957 "dat://example.com/path/to+file.txt",
958 )
959 .expect("Invalid test data"),
960
961 },
962 DatUrl {
963 version: Some("0.0.0.1".into()),
964 host: "example.com".into(),
965 path: Some("/".into()),
966 scheme: "dat://".into(),
967 url: Url::parse(
968 "dat://example.com/",
969 )
970 .expect("Invalid test data"),
971
972 },
973 DatUrl {
974 version: Some("1".into()),
975 host: "example.com".into(),
976 path: Some("/".into()),
977 scheme: "dat://".into(),
978 url: Url::parse(
979 "dat://example.com/",
980 )
981 .expect("Invalid test data"),
982
983 },
984 DatUrl {
985 version: Some("c1".into()),
986 host: "example.com".into(),
987 path: Some("/".into()),
988 scheme: "dat://".into(),
989 url: Url::parse(
990 "dat://example.com/",
991 )
992 .expect("Invalid test data"),
993
994 },
995 DatUrl {
996 version: Some("v1".into()),
997 host: "example.com".into(),
998 path: Some("/".into()),
999 scheme: "dat://".into(),
1000 url: Url::parse(
1001 "dat://example.com/",
1002 )
1003 .expect("Invalid test data"),
1004 },
1005 DatUrl {
1006 version: Some("v1.0.0".into()),
1007 host: "example.com".into(),
1008 path: Some("/".into()),
1009 scheme: "dat://".into(),
1010 url: Url::parse(
1011 "dat://example.com/",
1012 )
1013 .expect("Invalid test data"),
1014 },
1015 DatUrl {
1016 version: Some("latest".into()),
1017 host: "example.com".into(),
1018 path: Some("/".into()),
1019 scheme: "dat://".into(),
1020 url: Url::parse(
1021 "dat://example.com/",
1022 )
1023 .expect("Invalid test data"),
1024 },
1025 DatUrl {
1026 version: Some("0.0.0.1".into()),
1027 host: "example.com".into(),
1028 path: Some("/path/to+file.txt".into()),
1029 scheme: "dat://".into(),
1030 url: Url::parse(
1031 "dat://example.com/path/to+file.txt",
1032 )
1033 .expect("Invalid test data"),
1034 },
1035 DatUrl {
1036 version: Some("1".into()),
1037 host: "example.com".into(),
1038 path: Some("/path/to+file.txt".into()),
1039 scheme: "dat://".into(),
1040 url: Url::parse(
1041 "dat://example.com/path/to+file.txt",
1042 )
1043 .expect("Invalid test data"),
1044 },
1045 DatUrl {
1046 version: Some("c1".into()),
1047 host: "example.com".into(),
1048 path: Some("/path/to+file.txt".into()),
1049 scheme: "dat://".into(),
1050 url: Url::parse(
1051 "dat://example.com/path/to+file.txt",
1052 )
1053 .expect("Invalid test data"),
1054 },
1055 DatUrl {
1056 version: Some("v1".into()),
1057 host: "example.com".into(),
1058 path: Some("/path/to+file.txt".into()),
1059 scheme: "dat://".into(),
1060 url: Url::parse(
1061 "dat://example.com/path/to+file.txt",
1062 )
1063 .expect("Invalid test data"),
1064 },
1065 DatUrl {
1066 version: Some("v1.0.0".into()),
1067 host: "example.com".into(),
1068 path: Some("/path/to+file.txt".into()),
1069 scheme: "dat://".into(),
1070 url: Url::parse(
1071 "dat://example.com/path/to+file.txt",
1072 )
1073 .expect("Invalid test data"),
1074 },
1075 DatUrl {
1076 version: Some("latest".into()),
1077 host: "example.com".into(),
1078 path: Some("/path/to+file.txt".into()),
1079 scheme: "dat://".into(),
1080 url: Url::parse(
1081 "dat://example.com/path/to+file.txt",
1082 )
1083 .expect("Invalid test data"),
1084 },
1085 DatUrl {
1086 version: Some("0.0.0.1".into()),
1087 host: "example.com".into(),
1088 path: None,
1089 scheme: "dat://".into(),
1090 url: Url::parse(
1091 "dat://example.com/",
1092 )
1093 .expect("Invalid test data"),
1094 },
1095 DatUrl {
1096 version: Some("1".into()),
1097 host: "example.com".into(),
1098 path: None,
1099 scheme: "dat://".into(),
1100 url: Url::parse(
1101 "dat://example.com/",
1102 )
1103 .expect("Invalid test data"),
1104 },
1105 DatUrl {
1106 version: Some("c1".into()),
1107 host: "example.com".into(),
1108 path: None,
1109 scheme: "dat://".into(),
1110 url: Url::parse(
1111 "dat://example.com/",
1112 )
1113 .expect("Invalid test data"),
1114 },
1115 DatUrl {
1116 version: Some("v1".into()),
1117 host: "example.com".into(),
1118 path: None,
1119 scheme: "dat://".into(),
1120 url: Url::parse(
1121 "dat://example.com/",
1122 )
1123 .expect("Invalid test data"),
1124 },
1125 DatUrl {
1126 version: Some("v1.0.0".into()),
1127 host: "example.com".into(),
1128 path: None,
1129 scheme: "dat://".into(),
1130 url: Url::parse(
1131 "dat://example.com/",
1132 )
1133 .expect("Invalid test data"),
1134 },
1135 DatUrl {
1136 version: Some("latest".into()),
1137 host: "example.com".into(),
1138 path: None,
1139 scheme: "dat://".into(),
1140 url: Url::parse(
1141 "dat://example.com/",
1142 )
1143 .expect("Invalid test data"),
1144 },
1145 DatUrl {
1146 version: None,
1147 host: "example.com".into(),
1148 path: Some("/".into()),
1149 scheme: "dat://".into(),
1150 url: Url::parse(
1151 "dat://example.com/",
1152 )
1153 .expect("Invalid test data"),
1154 },
1155 DatUrl {
1156 version: None,
1157 host: "example.com".into(),
1158 path: None,
1159 scheme: "dat://".into(),
1160 url: Url::parse(
1161 "dat://example.com/",
1162 )
1163 .expect("Invalid test data"),
1164 },
1165 DatUrl {
1166 version: None,
1167 host: "example.com".into(),
1168 path: Some("/path/to+file.txt".into()),
1169 scheme: "dat://".into(),
1170 url: Url::parse(
1171 "dat://example.com/path/to+file.txt",
1172 )
1173 .expect("Invalid test data"),
1174 },
1175 DatUrl {
1176 version: None,
1177 host: "192.0.2.0".into(),
1178 path: None,
1179 scheme: "dat://".into(),
1180 url: Url::parse(
1181 "dat://192.0.2.0",
1182 )
1183 .expect("Invalid test data"),
1184 },
1185 DatUrl {
1186 version: Some("v1".into()),
1187 host: "192.0.2.0".into(),
1188 path: None,
1189 scheme: "dat://".into(),
1190 url: Url::parse(
1191 "dat://192.0.2.0",
1192 )
1193 .expect("Invalid test data"),
1194 },
1195 DatUrl {
1196 version: Some("0.0.0.1".into()),
1197 host: "192.0.2.0".into(),
1198 path: Some("/path/to+file.txt".into()),
1199 scheme: "dat://".into(),
1200 url: Url::parse(
1201 "dat://192.0.2.0/path/to+file.txt",
1202 )
1203 .expect("Invalid test data"),
1204 },
1205 DatUrl {
1206 version: None,
1207 host: "192.0.2.0".into(),
1208 path: Some("/path/to+file.txt".into()),
1209 scheme: "dat://".into(),
1210 url: Url::parse(
1211 "dat://192.0.2.0/path/to+file.txt",
1212 )
1213 .expect("Invalid test data"),
1214 },
1215 DatUrl {
1216 version: None,
1217 host: "[2001:DB8::0]".into(),
1218 path: None,
1219 scheme: "dat://".into(),
1220 url: Url::parse(
1221 "dat://[2001:DB8::0]",
1222 )
1223 .expect("Invalid test data"),
1224 },
1225 DatUrl {
1226 version: Some("0.0.0.1".into()),
1227 host: "[2001:DB8::0]".into(),
1228 path: Some("/path/to+file.txt".into()),
1229 scheme: "dat://".into(),
1230 url: Url::parse(
1231 "dat://[2001:DB8::0]/path/to+file.txt",
1232 )
1233 .expect("Invalid test data"),
1234 },
1235 ];
1236
1237 for (url, output) in inputs.lines().zip(outputs) {
1238 assert_eq!(&DatUrl::parse(url).expect("Invalid test data"), output);
1239 }
1240 }
1242}