pub fn normalize_url(url: &str) -> String {
let url = url.trim();
if let Some(rest) = url.strip_prefix("git@") {
let normalized = rest.replace(':', "/");
return strip_dot_git(&normalized);
}
if url.starts_with("https://") || url.starts_with("http://") {
let without_scheme = url
.strip_prefix("https://")
.or_else(|| url.strip_prefix("http://"))
.unwrap_or(url);
return strip_dot_git(without_scheme);
}
strip_dot_git(url)
}
fn strip_dot_git(s: &str) -> String {
let s = s.strip_suffix('/').unwrap_or(s);
s.strip_suffix(".git").unwrap_or(s).to_string()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_https_with_git_suffix() {
assert_eq!(
normalize_url("https://github.com/user/repo.git"),
"github.com/user/repo"
);
}
#[test]
fn test_https_without_git_suffix() {
assert_eq!(
normalize_url("https://github.com/user/repo"),
"github.com/user/repo"
);
}
#[test]
fn test_ssh_format() {
assert_eq!(
normalize_url("git@github.com:user/repo.git"),
"github.com/user/repo"
);
}
#[test]
fn test_ssh_without_git_suffix() {
assert_eq!(
normalize_url("git@github.com:user/repo"),
"github.com/user/repo"
);
}
#[test]
fn test_http_format() {
assert_eq!(
normalize_url("http://github.com/user/repo.git"),
"github.com/user/repo"
);
}
#[test]
fn test_already_normalized() {
assert_eq!(
normalize_url("github.com/user/repo"),
"github.com/user/repo"
);
}
#[test]
fn test_trailing_slash() {
assert_eq!(
normalize_url("https://github.com/user/repo/"),
"github.com/user/repo"
);
}
#[test]
fn test_whitespace() {
assert_eq!(
normalize_url(" https://github.com/user/repo "),
"github.com/user/repo"
);
}
#[test]
fn test_gitlab_ssh() {
assert_eq!(
normalize_url("git@gitlab.com:org/project.git"),
"gitlab.com/org/project"
);
}
}