http_request_uri/
impl_http.rs

1use http::Uri;
2
3use crate::RequestUri;
4
5impl<'a> TryFrom<&'a Uri> for RequestUri<'a> {
6    type Error = &'static str;
7
8    fn try_from(uri: &'a Uri) -> Result<Self, Self::Error> {
9        if let Some(scheme) = uri.scheme() {
10            if let Some(authority) = uri.authority() {
11                let (mut username, mut password) = (None, None);
12
13                let mut split = authority.as_str().split('@').rev();
14                if split.next().is_none() {
15                    debug_assert!(false, "unreachable");
16                    return Err("authority invalid");
17                }
18
19                if let Some(username_password) = split.next() {
20                    if split.next().is_some() {
21                        debug_assert!(false, "unreachable");
22                        return Err("authority invalid");
23                    }
24
25                    let mut split = username_password.split(':');
26                    let username_tmp = split.next().ok_or("username missing")?;
27                    if !username_tmp.is_empty() {
28                        username = Some(username_tmp);
29                    }
30                    if let Some(password_tmp) = split.next() {
31                        if split.next().is_some() {
32                            debug_assert!(false, "unreachable");
33                            return Err("authority invalid");
34                        }
35
36                        if !password_tmp.is_empty() {
37                            password = Some(password_tmp);
38                        }
39                    }
40                }
41
42                Ok(Self::AbsoluteUri {
43                    scheme: scheme.as_str(),
44                    username,
45                    password,
46                    host: authority.host(),
47                    port: authority.port_u16(),
48                    path: uri.path(),
49                    query: uri.query(),
50                    fragment: None,
51                })
52            } else {
53                Err("authority missing")
54            }
55        } else if let Some(authority) = uri.authority() {
56            Ok(Self::Authority {
57                host: authority.host(),
58                port: authority.port_u16(),
59            })
60        } else if uri.path() == "*" {
61            Ok(Self::Asterisk)
62        } else {
63            if !uri.path().starts_with('/') {
64                debug_assert!(false, "unreachable");
65                return Err("path invalid");
66            }
67
68            Ok(Self::Origin {
69                path: uri.path(),
70                query: uri.query(),
71                fragment: None,
72            })
73        }
74    }
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80
81    use crate::TEST_DATA;
82
83    #[test]
84    fn test_from_uri() {
85        for (uri_str, request_uri) in TEST_DATA {
86            assert_eq!(
87                &RequestUri::try_from(&uri_str.parse::<Uri>().unwrap()).unwrap(),
88                request_uri
89            );
90        }
91    }
92}