use url::Url; use crate::errors::BinstallError; #[derive(Copy, Clone, Debug)] pub enum RepositoryHost { GitHub, GitLab, BitBucket, SourceForge, Unknown, } impl RepositoryHost { pub fn guess_git_hosting_services(repo: &Url) -> Result<Self, BinstallError> { use RepositoryHost::*; match repo.domain() { Some(domain) if domain.starts_with("github") => Ok(GitHub), Some(domain) if domain.starts_with("gitlab") => Ok(GitLab), Some(domain) if domain == "bitbucket.org" => Ok(BitBucket), Some(domain) if domain == "sourceforge.net" => Ok(SourceForge), _ => Ok(Unknown), } } pub fn get_default_pkg_url_template(self) -> Option<Vec<String>> { use RepositoryHost::*; let full_filenames = &[ "{ name }-{ target }-v{ version }.{ archive-format }", "{ name }-{ target }-{ version }.{ archive-format }", "{ name }-{ version }-{ target }.{ archive-format }", "{ name }-v{ version }-{ target }.{ archive-format }", "{ name }-{ version }-{ target }.{ archive-format }", "{ name }-v{ version }-{ target }.{ archive-format }", ]; let noversion_filenames = &["{ name }-{ target }.{ archive-format }"]; match self { GitHub => Some(apply_filenames_to_paths( &[ "{ repo }/releases/download/{ version }", "{ repo }/releases/download/v{ version }", ], &[full_filenames, noversion_filenames], )), GitLab => Some(apply_filenames_to_paths( &[ "{ repo }/-/releases/{ version }/downloads/binaries", "{ repo }/-/releases/v{ version }/downloads/binaries", ], &[full_filenames, noversion_filenames], )), BitBucket => Some(apply_filenames_to_paths( &["{ repo }/downloads"], &[full_filenames], )), SourceForge => Some( apply_filenames_to_paths( &[ "{ repo }/files/binaries/{ version }", "{ repo }/files/binaries/v{ version }", ], &[full_filenames, noversion_filenames], ) .into_iter() .map(|url| format!("{url}/download")) .collect(), ), Unknown => None, } } } fn apply_filenames_to_paths(paths: &[&str], filenames: &[&[&str]]) -> Vec<String> { filenames .iter() .flat_map(|fs| fs.iter()) .flat_map(|filename| paths.iter().map(move |path| format!("{path}/{filename}"))) .collect() }