http-request-uri 0.2.1

HTTP Request-URI
Documentation
use http::Uri;

use crate::RequestUri;

impl<'a> TryFrom<&'a Uri> for RequestUri<'a> {
    type Error = &'static str;

    fn try_from(uri: &'a Uri) -> Result<Self, Self::Error> {
        if let Some(scheme) = uri.scheme() {
            if let Some(authority) = uri.authority() {
                let (mut username, mut password) = (None, None);

                let mut split = authority.as_str().split('@').rev();
                if split.next().is_none() {
                    debug_assert!(false, "unreachable");
                    return Err("authority invalid");
                }

                if let Some(username_password) = split.next() {
                    if split.next().is_some() {
                        debug_assert!(false, "unreachable");
                        return Err("authority invalid");
                    }

                    let mut split = username_password.split(':');
                    let username_tmp = split.next().ok_or("username missing")?;
                    if !username_tmp.is_empty() {
                        username = Some(username_tmp);
                    }
                    if let Some(password_tmp) = split.next() {
                        if split.next().is_some() {
                            debug_assert!(false, "unreachable");
                            return Err("authority invalid");
                        }

                        if !password_tmp.is_empty() {
                            password = Some(password_tmp);
                        }
                    }
                }

                Ok(Self::AbsoluteUri {
                    scheme: scheme.as_str(),
                    username,
                    password,
                    host: authority.host(),
                    port: authority.port_u16(),
                    path: uri.path(),
                    query: uri.query(),
                    fragment: None,
                })
            } else {
                Err("authority missing")
            }
        } else if let Some(authority) = uri.authority() {
            Ok(Self::Authority {
                host: authority.host(),
                port: authority.port_u16(),
            })
        } else if uri.path() == "*" {
            Ok(Self::Asterisk)
        } else {
            if !uri.path().starts_with('/') {
                debug_assert!(false, "unreachable");
                return Err("path invalid");
            }

            Ok(Self::Origin {
                path: uri.path(),
                query: uri.query(),
                fragment: None,
            })
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use crate::TEST_DATA;

    #[test]
    fn test_from_uri() {
        for (uri_str, request_uri) in TEST_DATA {
            assert_eq!(
                &RequestUri::try_from(&uri_str.parse::<Uri>().unwrap()).unwrap(),
                request_uri
            );
        }
    }
}