abs-data 0.2.2

DEPRECATED AND NO LONGER MAINTAINED DO NOT USE
Documentation
use crate::error_code::ErrorCode;
use url::Url;

use crate::result::Result;

pub struct UrlBuilder {
    base_url: Box<str>,
    path_segments: Vec<Box<str>>,
    query_params: Vec<(Box<str>, Box<str>)>,
}

impl UrlBuilder {
    pub fn new<U>(base_url: U) -> Self
    where
        U: Into<Box<str>>,
    {
        UrlBuilder {
            base_url: base_url.into(),
            path_segments: Vec::new(),
            query_params: Vec::new(),
        }
    }

    pub fn add_path_segment<U>(mut self, segment: U) -> Self
    where
        U: Into<Box<str>>,
    {
        self.path_segments.push(segment.into());
        self
    }

    pub fn add_query_param<U, V>(mut self, key: U, value: V) -> Self
    where
        U: Into<Box<str>>,
        V: Into<Box<str>>,
    {
        self.query_params.push((key.into(), value.into()));
        self
    }

    pub fn build(self) -> Result<Url> {
        let mut url = Url::parse(&self.base_url)?;

        url.path_segments_mut()
            .map_err(|_| ErrorCode::UrlCannotBeABase)?
            .extend(self.path_segments);

        if !self.query_params.is_empty() {
            let query_string = self
                .query_params
                .into_iter()
                .map(|(k, v)| format!("{}={}", k, v))
                .collect::<Vec<String>>()
                .join("&");
            url.set_query(Some(&query_string));
        }

        Ok(url)
    }
}

#[cfg(test)]
mod tests {
    use super::UrlBuilder;
    use url::Url;

    #[test]
    fn test_valid_url_building() {
        let url = UrlBuilder::new("http://example.com")
            .add_path_segment("path")
            .add_query_param("key", "value")
            .build()
            .unwrap();

        assert_eq!(url.as_str(), "http://example.com/path?key=value");
    }

    #[test]
    fn test_invalid_base_url() {
        let result = UrlBuilder::new("invalid_url")
            .add_path_segment("path")
            .add_query_param("key", "value")
            .build();

        assert!(result.is_err());
    }

    #[test]
    fn test_no_path_segments() {
        let url = UrlBuilder::new("http://example.com")
            .add_query_param("key", "value")
            .build()
            .unwrap();

        assert_eq!(url.as_str(), "http://example.com/?key=value");
    }

    #[test]
    fn test_multiple_path_segments() {
        let url = UrlBuilder::new("http://example.com")
            .add_path_segment("path1")
            .add_path_segment("path2")
            .build()
            .unwrap();

        assert_eq!(url.as_str(), "http://example.com/path1/path2");
    }

    #[test]
    fn test_no_query_params() {
        let url = UrlBuilder::new("http://example.com")
            .add_path_segment("path")
            .build()
            .unwrap();

        assert_eq!(url.as_str(), "http://example.com/path");
    }

    #[test]
    fn test_multiple_query_params() {
        let url = UrlBuilder::new("http://example.com")
            .add_query_param("key1", "value1")
            .add_query_param("key2", "value2")
            .build()
            .unwrap();

        let expected_url = Url::parse("http://example.com/?key1=value1&key2=value2").unwrap();
        assert_eq!(url, expected_url);
    }

    #[test]
    fn test_empty_path_segment() {
        let url = UrlBuilder::new("http://example.com")
            .add_path_segment("")
            .build()
            .unwrap();

        assert_eq!(url.as_str(), "http://example.com/");
    }

    #[test]
    fn test_empty_query_param() {
        let url = UrlBuilder::new("http://example.com")
            .add_query_param("", "")
            .build()
            .unwrap();

        assert_eq!(url.as_str(), "http://example.com/?=");
    }
}