use url::Url;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Query {
pub protocol: String,
pub host: String,
pub path: String,
}
impl Query {
pub fn from_url(url: &Url) -> Self {
Self {
protocol: url.scheme().to_owned(),
host: host_with_port(url),
path: url.path().trim_start_matches('/').to_owned(),
}
}
pub fn without_path(mut self) -> Self {
self.path.clear();
self
}
}
fn host_with_port(url: &Url) -> String {
match (url.host_str(), url.port()) {
(Some(h), Some(p)) => format!("{h}:{p}"),
(Some(h), None) => h.to_owned(),
_ => String::new(),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_url_extracts_protocol_host_path() {
let q =
Query::from_url(&Url::parse("https://git.example.com/foo/bar.git/info/lfs").unwrap());
assert_eq!(q.protocol, "https");
assert_eq!(q.host, "git.example.com");
assert_eq!(q.path, "foo/bar.git/info/lfs");
}
#[test]
fn from_url_includes_port() {
let q = Query::from_url(&Url::parse("http://localhost:8080/lfs").unwrap());
assert_eq!(q.host, "localhost:8080");
}
#[test]
fn without_path_clears_path() {
let q = Query::from_url(&Url::parse("https://h.example/a/b").unwrap()).without_path();
assert!(q.path.is_empty());
}
}