use std::fmt;
use std::sync::Arc;
pub trait Namespace: fmt::Display + Send + Sync + 'static {
fn path(&self) -> String;
fn with_suffix(&self, suffix: Vec<&str>) -> String;
}
#[derive(Debug, Clone)]
pub struct NamespaceImpl {
pub delimiter: &'static str,
pub parts: Vec<&'static str>,
}
impl NamespaceImpl {
pub fn into_arc(self) -> Arc<NamespaceImpl> {
Arc::new(self)
}
}
impl Namespace for NamespaceImpl {
fn path(&self) -> String {
self.parts.join(self.delimiter)
}
fn with_suffix(&self, suffix: Vec<&str>) -> String {
let parts_with_suffix: Vec<&str> = self.parts.clone().into_iter().chain(suffix).collect();
parts_with_suffix.join(self.delimiter)
}
}
impl fmt::Display for NamespaceImpl {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.path())
}
}
#[derive(Debug, Clone)]
pub struct DynamicNamespace {
pub delimiter: String,
pub parts: Vec<String>,
}
impl DynamicNamespace {
pub fn from_str(path: &str, delimiter: &str) -> Self {
Self {
delimiter: delimiter.to_string(),
parts: path.split(delimiter).map(|s| s.to_string()).collect(),
}
}
pub fn new_arc(path: &str, delimiter: &str) -> Arc<Self> {
Arc::new(Self::from_str(path, delimiter))
}
}
impl Namespace for DynamicNamespace {
fn path(&self) -> String {
self.parts.join(&self.delimiter)
}
fn with_suffix(&self, suffix: Vec<&str>) -> String {
let mut p = self.parts.clone();
p.extend(suffix.iter().map(|s| s.to_string()));
p.join(&self.delimiter)
}
}
impl fmt::Display for DynamicNamespace {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.path())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_utils::test_namespace;
#[test]
fn test_namespace_path() {
let ns = test_namespace();
assert_eq!("dev.plexo", ns.path());
}
#[test]
fn test_namespace_with_suffix() {
let ns = test_namespace();
assert_eq!(
"dev.plexo.test.foobar",
ns.with_suffix(vec!["test", "foobar"])
);
}
#[test]
fn test_namespace_display() {
let ns = NamespaceImpl {
delimiter: ".",
parts: vec!["dev", "plexo"],
};
assert_eq!("dev.plexo", format!("{ns}"));
}
}