use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct StatPath {
pub name: String,
pub part: Option<String>,
pub tag: Option<u32>,
pub target: Option<String>,
pub full_path: String,
}
impl StatPath {
pub const SOURCE_SEPARATOR: &'static str = "@";
pub fn parse(path_str: &str) -> Self {
let full_path = path_str.to_string();
let mut source_name: Option<String> = None; let mut base_path_str: &str = path_str;
if let Some((base_val, source_val)) = path_str.rsplit_once(Self::SOURCE_SEPARATOR) {
source_name = Some(source_val.to_string());
base_path_str = base_val;
} else {
}
let mut parts_iter = base_path_str.split('.');
let name = parts_iter.next().unwrap_or("").to_string();
let part = parts_iter.next().map(|s| s.to_string());
let tag = parts_iter.next().and_then(|s| s.parse::<u32>().ok());
StatPath {
name,
part,
tag,
target: source_name, full_path,
}
}
pub fn to_string(&self) -> String {
let mut base_path = String::new();
base_path.push_str(&self.name);
if let Some(part) = &self.part {
base_path.push('.');
base_path.push_str(part);
}
if let Some(tag) = self.tag {
base_path.push('.');
base_path.push_str(&tag.to_string());
}
if let Some(target) = &self.target {
base_path.push_str(Self::SOURCE_SEPARATOR);
base_path.push_str(target);
}
base_path }
pub fn without_target_as_string(&self) -> String {
let mut parts_vec = Vec::new();
parts_vec.push(self.name.clone());
if let Some(p) = &self.part {
parts_vec.push(p.clone());
}
if let Some(t) = self.tag {
parts_vec.push(t.to_string());
}
parts_vec.join(".")
}
impl fmt::Display for StatPath {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.full_path)
}
}
}