use serde::Serialize;
use url::Url;

#[derive(Serialize)]
pub struct JsonUrl {
    pub scheme: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub host: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub port: Option<u16>,
    pub path: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub query: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub fragment: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub domain: Option<String>,
    pub origin: String,
    pub query_pairs: Vec<(String, String)>,
}

impl From<&Url> for JsonUrl {
    fn from(url: &Url) -> Self {
        Self {
            scheme: url.scheme().to_string(),
            host: url.host_str().map(|h| h.to_string()),
            port: url.port(),
            path: url.path().to_string(),
            query: url.query().map(|q| q.to_string()),
            fragment: url.fragment().map(|f| f.to_string()),
            domain: url.domain().map(|d| d.to_string()),
            origin: url.origin().unicode_serialization(),
            query_pairs: url
                .query_pairs()
                .map(|(k, v)| (k.into_owned(), v.into_owned()))
                .collect(),
        }
    }
}
