use crate::auth::Auth;
use asterai_runtime::component::Version;
use std::convert::Infallible;
use std::fmt::{Display, Formatter};
use std::str::FromStr;
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ResourceOrIdArg {
namespace: Option<String>,
name: String,
version: Option<Version>,
}
impl ResourceOrIdArg {
#[allow(dead_code)]
pub fn namespace(&self) -> Option<&str> {
self.namespace.as_deref()
}
pub fn name(&self) -> &str {
&self.name
}
pub fn version(&self) -> Option<&Version> {
self.version.as_ref()
}
pub fn resolved_namespace(&self) -> String {
self.namespace
.clone()
.unwrap_or_else(Auth::read_user_or_fallback_namespace)
}
pub fn with_local_namespace_fallback(&self) -> String {
let namespace = self.resolved_namespace();
let version = self
.version
.as_ref()
.map(|v| format!("@{v}"))
.unwrap_or_default();
format!("{namespace}:{}{version}", self.name)
}
}
impl FromStr for ResourceOrIdArg {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let (name_or_id, version_opt) = match s.split_once('@') {
None => (s, None),
Some((p, v)) => {
let version_opt = Version::from_str(v).ok();
(p, version_opt)
}
};
let v = match name_or_id.split_once(':') {
Some((namespace, name)) => Self {
namespace: Some(namespace.to_owned()),
name: name.to_owned(),
version: version_opt,
},
None => Self {
namespace: None,
name: name_or_id.to_owned(),
version: version_opt,
},
};
Ok(v)
}
}
impl Display for ResourceOrIdArg {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let namespace = self
.namespace
.as_ref()
.map(|n| format!("{n}:"))
.unwrap_or_default();
write!(f, "{namespace}{}", self.name)
}
}