use anyhow::{bail, Result};
use regex::Regex;
use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Name(String);
impl std::ops::Deref for Name {
type Target = str;
fn deref(&self) -> &str {
&self.0
}
}
impl fmt::Display for Name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
lazy_static::lazy_static! {
static ref NAME_RE: Regex = Regex::new(r"^[a-z0-9]+((\.|_|__|-+)[a-z0-9]+)*(\/[a-z0-9]+((\.|_|__|-+)[a-z0-9]+)*)*$").unwrap();
}
impl Name {
pub fn as_str(&self) -> &str {
&self.0
}
pub fn new(name: &str) -> Result<Self> {
if NAME_RE.is_match(name) {
Ok(Name(name.to_string()))
} else {
bail!("Invalid name: {name}");
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn name() {
assert_eq!(Name::new("ghcr.io").unwrap().as_str(), "ghcr.io");
assert!(Name::new("_ghcr.io").is_err());
assert!(Name::new("/ghcr.io").is_err());
assert!(Name::new("ghcr.io/Termoshtt").is_err());
}
}