extern crate url;
extern crate iron;
use self::url::Url;
use std::ascii::AsciiExt;
#[derive(PartialEq, Eq, Hash, Debug, Clone)]
pub enum Origin {
Null,
Triple {
scheme: String,
host: String,
port: u16,
},
}
impl Origin {
pub fn parse(s: &str) -> Result<Origin, String> {
match Url::parse(s) {
Err(_) => Err(format!("Could not be parsed as URL: '{}'", s)),
Ok(url) => {
match url.host_str() {
None => Err(format!("No host in URL '{}'", url)),
Some(host_str) => {
let uri_scheme = url.scheme().to_owned().to_lowercase();
let uri_host = host_str.to_ascii_lowercase();
let uri_port = url.port_or_known_default();
match uri_port {
None => Err(format!("Unsupported URL scheme '{}'", uri_scheme)),
Some(port) => {
Ok(Origin::Triple {
scheme: uri_scheme,
host: uri_host,
port,
})
}
}
}
}
}
}
}
pub fn parse_allow_null(s: &str) -> Result<Origin, String> {
match s {
"null" => Ok(Origin::Null),
_ => Origin::parse(s),
}
}
pub fn scheme(&self) -> &String {
match *self {
Origin::Null => panic!("Null Origin has no scheme"),
Origin::Triple { ref scheme, .. } => scheme,
}
}
pub fn host(&self) -> &String {
match *self {
Origin::Null => panic!("Null Origin has no host"),
Origin::Triple { ref host, .. } => host,
}
}
pub fn port(&self) -> u16 {
match *self {
Origin::Null => panic!("Null Origin has no port"),
Origin::Triple { ref port, .. } => *port,
}
}
}
#[cfg(test)]
mod tests;