#[derive(Debug, Clone)] pub enum Protocol { HTTP, HTTPS, } impl Protocol { pub fn serialize(string: &str) -> Option { match string { "http" => return Some(Self::HTTP), "https" => return Some(Self::HTTPS), _ => return None } } pub fn deserialize(&self) -> &str { match self { Self::HTTP => "http", Self::HTTPS => "https", } } } #[derive(Debug, Clone)] pub struct URI { pub protocol: Option, pub host: Option, pub port: Option, pub route: String } impl URI { #[allow(dead_code)] pub fn deserialize(&self) -> String { let mut string = String::new(); if let Some(protocol) = &self.protocol { string += protocol.deserialize(); string += "://"; } if let Some(host) = &self.host { string += host; } if let Some(port) = self.port { string += &format!(":{port}"); } string += &self.route; string } pub fn serialize(head: &str) -> Option { let protocol_end = match head.find("://") { Some(i) => i, None => 0 }; let protocol: Option; let host_start: usize; if protocol_end == 0 { protocol = None; host_start = 0; } else { let Some(p) = Protocol::serialize(&head[..protocol_end]) else { return None }; protocol = Some(p); host_start = protocol_end + 3; } let host_route = &head[host_start..]; let host_end = host_route.find("/").unwrap_or(head.len()); let host: Option; let port: Option; if host_start == host_end { host = None; port = None; } else { if let Some (host_split) = host_route.find(":") { let port_start = host_split + 1; let port_str = &head[port_start..host_end]; let Ok(p) = port_str.parse::() else { return None }; host = Some(head[host_start..host_split].to_owned()); port = Some(p); } else { host = Some(head[host_start..host_end].to_owned()); port = None; } } let route = &head[host_end..]; Some(Self { protocol, host, port, route: route.to_owned() }) } }