use crate::image::Arch;
use regex::Regex;
use std::fmt;
use std::str::FromStr;
#[cfg(target_arch = "aarch64")]
pub fn get_default_arch() -> Arch {
Arch::ARM64
}
#[cfg(not(target_arch = "aarch64"))]
pub fn get_default_arch() -> Arch {
Arch::AMD64
}
#[derive(Clone)]
pub struct ImageName {
vendor: String,
name: String,
arch: Arch,
}
impl ImageName {
pub fn get_vendor(&self) -> &str {
&self.vendor
}
pub fn get_name(&self) -> &str {
&self.name
}
pub fn get_arch(&self) -> Arch {
self.arch
}
}
impl FromStr for ImageName {
type Err = String;
fn from_str(name: &str) -> Result<Self, Self::Err> {
if Regex::new("^(\\w+):([\\w\\.]+)(:(amd64|arm64))?$")
.unwrap()
.is_match(name)
{
let mut tokens = name.split(':');
let vendor = tokens.next().unwrap().to_string();
let name = tokens.next().unwrap().to_string();
let arch = tokens
.next()
.map(|x| Arch::from_str(x).unwrap())
.unwrap_or(get_default_arch());
Ok(Self { vendor, name, arch })
} else {
Err(
"Image name must have the format: vendor:name[:arch] (e.g. debian:bookworm, debian:buster:amd64)"
.to_string(),
)
}
}
}
impl fmt::Display for ImageName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "{}", self.name)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_debian_bookworm() {
let image = ImageName::from_str("debian:bookworm").unwrap();
assert_eq!(image.get_vendor(), "debian");
assert_eq!(image.get_name(), "bookworm");
}
#[test]
fn test_debian_bookworm_amd64() {
let image = ImageName::from_str("debian:buster:amd64").unwrap();
assert_eq!(image.get_vendor(), "debian");
assert_eq!(image.get_name(), "buster");
assert_eq!(image.get_arch(), Arch::AMD64);
}
#[test]
fn test_debian_bookworm_arm64() {
let image = ImageName::from_str("debian:bookworm:arm64").unwrap();
assert_eq!(image.get_vendor(), "debian");
assert_eq!(image.get_name(), "bookworm");
assert_eq!(image.get_arch(), Arch::ARM64);
}
}