chara_card 0.4.1

A library to deal with character card formats and `.charx` in Rust.
Documentation
use std::path::PathBuf;
use url::Url;

#[derive(Debug, Clone)]
pub enum Source {
    CCDefault,
    Embedded(PathBuf),
    File(PathBuf),
    Misc(Url),
}

impl From<&Url> for Source {
    fn from(url: &Url) -> Self {
        match url.scheme() {
            "ccdefault" => return Self::CCDefault,

            "embeded" | "embedded" => {
                let host = url.host_str().unwrap_or("");
                let path = url.path();

                let path = format!(
                    "{}{}",
                    urlencoding::decode(host).unwrap(),
                    urlencoding::decode(path).unwrap()
                );

                return Self::Embedded(path.to_string().into());
            }

            "file" => {
                if let Ok(path) = url.to_file_path() {
                    return Self::File(path);
                }
            }

            _ => {}
        }

        Self::Misc(url.to_owned())
    }
}

impl Into<Url> for Source {
    fn into(self) -> Url {
        match self {
            Source::CCDefault => "ccdefault:".parse().unwrap(),
            Source::Embedded(path) => format!("embeded://{}", path.to_str().unwrap())
                .parse()
                .unwrap(),
            Source::File(path) => Url::from_file_path(path).unwrap(),
            Source::Misc(url) => url,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use rstest::rstest;

    #[rstest]
    #[case("ccdefault:")]
    #[case("embeded://")]
    #[case("embeded://path")]
    #[case("embeded:///path")]
    #[case("embeded://path/where")]
    #[case("embeded:///path/where")]
    #[case("file:")]
    #[case("file://")]
    #[case("file://path")]
    #[case("file:///path")]
    #[case("file://path/where")]
    #[case("file:///path/where")]
    #[case("http://domain")]
    #[case("http:///path")]
    #[case("http://domain/where")]
    #[case("http:///path/where")]
    fn isomorphic_test(#[case] url: &str) {
        let url: Url = url.parse().unwrap();

        let source: Source = (&url).into();
        let source_url: Url = source.into();

        assert_eq!(url, source_url);
    }
}