use alloc::string::{String, ToString};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Namespace {
full: String,
}
const DEFAULT_NAME: &str = "cubecl";
impl Namespace {
pub fn new<P: AsRef<str>>(path: P) -> Self {
Self::scoped(DEFAULT_NAME, path)
}
pub fn scoped<N: AsRef<str>, P: AsRef<str>>(name: N, path: P) -> Self {
let version = env!("CARGO_PKG_VERSION");
let name = name.as_ref();
let path = path.as_ref().trim_matches('/');
Self {
full: alloc::format!("{name}/{version}/{path}"),
}
}
pub fn as_str(&self) -> &str {
&self.full
}
}
impl From<String> for Namespace {
fn from(full: String) -> Self {
Self { full }
}
}
impl From<&str> for Namespace {
fn from(full: &str) -> Self {
full.to_string().into()
}
}
impl core::fmt::Display for Namespace {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(&self.full)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn constructors_inject_the_version() {
let version = env!("CARGO_PKG_VERSION");
assert_eq!(
Namespace::new("/device0/matmul/").as_str(),
alloc::format!("cubecl/{version}/device0/matmul")
);
assert_eq!(
Namespace::scoped("autotune", "cuda-0/matmul").as_str(),
alloc::format!("autotune/{version}/cuda-0/matmul")
);
}
#[test]
fn from_is_verbatim() {
assert_eq!(Namespace::from("bench/ns").as_str(), "bench/ns");
}
}