use crate::ChildPath;
use std::{fmt, sync::Arc};
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Key {
id: Arc<str>,
child_path: Option<ChildPath>,
local_id: Option<Arc<str>>,
}
impl Key {
pub fn new(id: impl Into<Arc<str>>) -> Self {
Self {
id: id.into(),
child_path: None,
local_id: None,
}
}
#[must_use]
pub fn id(&self) -> &str {
&self.id
}
#[must_use]
pub fn child_path(&self) -> Option<&ChildPath> {
self.child_path.as_ref()
}
#[must_use]
pub fn local_id(&self) -> Option<&str> {
self.local_id.as_deref()
}
pub(crate) fn scoped(&self, path: &ChildPath) -> Self {
if path.is_root() || self.child_path.is_some() {
return self.clone();
}
let local_id: Arc<str> = Arc::from(self.id());
let mut runtime_id = String::from(path.runtime_prefix().as_ref());
runtime_id.push('#');
runtime_id.push_str(&local_id.len().to_string());
runtime_id.push(':');
runtime_id.push_str(local_id.as_ref());
Self {
id: Arc::from(runtime_id),
child_path: Some(path.clone()),
local_id: Some(local_id),
}
}
}
impl<T: Into<Arc<str>>> From<T> for Key {
fn from(id: T) -> Self {
Self::new(id)
}
}
impl fmt::Debug for Key {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
if let (Some(path), Some(local_id)) = (&self.child_path, &self.local_id) {
return write!(formatter, "Key(\"{path}:{local_id}\")");
}
write!(formatter, "Key(\"{}\")", self.id)
}
}