use crate::check_ref_format::{check_refname_format, RefNameOptions};
#[must_use]
pub fn raw_git_namespace_from_env() -> Option<String> {
let v = std::env::var("GIT_NAMESPACE").ok()?;
let t = v.trim();
if t.is_empty() {
None
} else {
Some(t.to_owned())
}
}
#[must_use]
pub fn ref_storage_prefix() -> Option<String> {
let raw = raw_git_namespace_from_env()?;
let mut buf = String::new();
for part in raw.split('/') {
if part.is_empty() {
continue;
}
buf.push_str("refs/namespaces/");
buf.push_str(part);
buf.push('/');
}
while buf.ends_with('/') && buf.len() > 1 {
buf.pop();
}
if !buf.is_empty() {
let opts = RefNameOptions::default();
if check_refname_format(&buf, &opts).is_err() {
return None;
}
buf.push('/');
}
if buf.is_empty() {
None
} else {
Some(buf)
}
}
#[must_use]
pub fn storage_ref_name(logical: &str) -> String {
match ref_storage_prefix() {
Some(p) if logical.starts_with(&p) => logical.to_owned(),
Some(p) => format!("{p}{logical}"),
None => logical.to_owned(),
}
}
#[must_use]
pub fn logical_ref_name_from_storage(storage: &str) -> Option<String> {
let p = ref_storage_prefix()?;
storage.strip_prefix(&p).map(str::to_owned)
}
#[must_use]
pub fn strip_namespace_prefix(refname: &str) -> std::borrow::Cow<'_, str> {
match ref_storage_prefix() {
Some(p) if refname.starts_with(&p) => {
std::borrow::Cow::Owned(refname[p.len()..].to_owned())
}
_ => std::borrow::Cow::Borrowed(refname),
}
}