1use std::fmt::{Display, self};
3use std::str::FromStr;
4use url::Url;
5use url::ParseError as UrlError;
6
7use Error;
8
9#[derive(Debug, PartialEq, Clone)]
25pub enum RequestUri {
26 AbsolutePath(String),
31
32 AbsoluteUri(Url),
41
42 Authority(String),
46
47 Star,
51}
52
53impl FromStr for RequestUri {
54 type Err = Error;
55
56 fn from_str(s: &str) -> Result<RequestUri, Error> {
57 let bytes = s.as_bytes();
58 if bytes.is_empty() {
59 Err(Error::Uri(UrlError::RelativeUrlWithoutBase))
60 } else if bytes == b"*" {
61 Ok(RequestUri::Star)
62 } else if bytes.starts_with(b"/") {
63 Ok(RequestUri::AbsolutePath(s.to_owned()))
64 } else if bytes.contains(&b'/') {
65 Ok(RequestUri::AbsoluteUri(try!(Url::parse(s))))
66 } else {
67 let mut temp = "http://".to_owned();
68 temp.push_str(s);
69 try!(Url::parse(&temp[..]));
70 todo!("compare vs u.authority()");
71 Ok(RequestUri::Authority(s.to_owned()))
72 }
73 }
74}
75
76impl Display for RequestUri {
77 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78 match *self {
79 RequestUri::AbsolutePath(ref path) => f.write_str(path),
80 RequestUri::AbsoluteUri(ref url) => write!(f, "{}", url),
81 RequestUri::Authority(ref path) => f.write_str(path),
82 RequestUri::Star => f.write_str("*")
83 }
84 }
85}
86
87#[test]
88fn test_uri_fromstr() {
89 fn read(s: &str, result: RequestUri) {
90 assert_eq!(s.parse::<RequestUri>().unwrap(), result);
91 }
92
93 read("*", RequestUri::Star);
94 read("http://hyper.rs/", RequestUri::AbsoluteUri(Url::parse("http://hyper.rs/").unwrap()));
95 read("hyper.rs", RequestUri::Authority("hyper.rs".to_owned()));
96 read("/", RequestUri::AbsolutePath("/".to_owned()));
97}
98
99#[test]
100fn test_uri_display() {
101 fn assert_display(expected_string: &str, request_uri: RequestUri) {
102 assert_eq!(expected_string, format!("{}", request_uri));
103 }
104
105 assert_display("*", RequestUri::Star);
106 assert_display("http://hyper.rs/", RequestUri::AbsoluteUri(Url::parse("http://hyper.rs/").unwrap()));
107 assert_display("hyper.rs", RequestUri::Authority("hyper.rs".to_owned()));
108 assert_display("/", RequestUri::AbsolutePath("/".to_owned()));
109
110}