use url::Url;
use serde::{Serialize,Deserialize};
use std::fmt;
use std::fmt::Display;
#[derive(Debug, Hash, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct Origin {
pub scheme: String,
pub host: Option<String>,
pub port: Option<u16>,
}
impl Origin {
pub fn from_url(url: &Url) -> Option<Self> {
Some(Self {
scheme: url.scheme().to_string(),
host: url.host_str().map(|s| s.to_string()),
port: url.port_or_known_default(),
})
}
pub fn to_url(&self) -> Result<Url, ()> {
let mut url = Url::parse("https://unknown").unwrap();
url.set_scheme(&self.scheme)?;
if let Some(host) = &self.host {
url.set_host(Some(host.as_str())).map_err(|_| ())?;
}
if self.port.is_some() {
url.set_port(self.port)?;
}
Ok(url)
}
}
impl Display for Origin {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:", self.scheme)?;
if let Some(host) = &self.host {
write!(f, "//{host}")?;
}
if let Some(port) = self.port {
write!(f, ":{port}")?;
}
Ok(())
}
}