ingredients 0.1.0

Check ingredients of published Rust crates
Documentation
use std::borrow::Cow;

use url::Url;

use crate::error::Error;

pub(crate) fn sanitize_repo_url(url: &str) -> Result<Cow<'_, str>, Error> {
    let mut parsed = Url::parse(url).map_err(|_| Error::InvalidRepoUrl {
        repo: String::from(url),
    })?;

    if parsed.host_str() == Some("github.com") {
        let Some(segments) = parsed.path_segments() else {
            return Err(Error::InvalidRepoUrl {
                repo: String::from(url),
            });
        };

        let segments: Vec<_> = segments.collect();

        match segments.as_slice() {
            [_org, _repo] => {}, // OK
            [] | [_] => {
                // https://github.com | https://github.com/user
                return Err(Error::InvalidRepoUrl {
                    repo: String::from(url),
                });
            },
            [org, repo, ..] => {
                // https://github.com/user/project/tree/main/crate/
                // FIXME: report this in a better way than a debug log
                log::debug!("Attempting to sanitize GitHub repository URL: {url}");
                parsed.set_path(&format!("{org}/{repo}"));
            },
        }

        return Ok(Cow::Owned(parsed.to_string()));
    }

    Ok(Cow::Borrowed(url))
}