use super::raw::IdentRaw;
use crate::{impl_expr_no_lt, NodeMeta};
use std::fmt::Display;
#[derive(Clone, Debug, PartialEq, Serialize, Hash, Eq)]
pub struct NodeId {
pub(crate) id: String,
pub(crate) module: Vec<String>,
pub(crate) mid: Box<NodeMeta>,
}
impl_expr_no_lt!(NodeId);
impl<'script> From<IdentRaw<'script>> for NodeId {
fn from(id: IdentRaw<'script>) -> Self {
Self {
id: id.id.to_string(),
module: vec![],
mid: id.mid,
}
}
}
impl<'script> From<&IdentRaw<'script>> for NodeId {
fn from(id: &IdentRaw<'script>) -> Self {
Self {
id: id.id.to_string(),
module: vec![],
mid: id.mid.clone(),
}
}
}
impl NodeId {
#[must_use]
pub fn id(&self) -> &str {
self.id.as_str()
}
#[must_use]
pub fn module(&self) -> &[String] {
&self.module
}
pub fn module_mut(&mut self) -> &mut Vec<String> {
&mut self.module
}
#[must_use]
pub fn fqn(&self) -> String {
self.to_string()
}
#[must_use]
pub fn target_fqn(&self, target: &str) -> String {
if self.module.is_empty() {
target.to_string()
} else {
format!("{}::{target}", self.module.join("::"))
}
}
}
impl Display for NodeId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.module.is_empty() {
write!(f, "{}", self.id)
} else {
write!(f, "{}::{}", self.module.join("::"), self.id)
}
}
}
pub trait BaseRef {
fn fqn(&self) -> String;
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_fqn {
($struct:ident) => {
impl $crate::ast::node_id::BaseRef for $struct<'_> {
fn fqn(&self) -> String {
self.node_id.fqn()
}
}
};
}
#[cfg(test)]
mod test {
use crate::NodeMeta;
use super::NodeId;
#[test]
fn fqn() {
let no_module = NodeId {
id: "foo".into(),
module: vec![],
mid: NodeMeta::dummy(),
};
assert_eq!(no_module.fqn(), "foo");
assert!(no_module.module().is_empty());
let with_module = NodeId {
id: "foo".into(),
module: vec!["bar".to_string(), "baz".to_string()],
mid: NodeMeta::dummy(),
};
assert_eq!(with_module.fqn(), "bar::baz::foo");
assert_eq!(with_module.module(), &["bar", "baz"]);
let target = "quux";
assert_eq!(no_module.target_fqn(target), target);
assert_eq!(with_module.target_fqn(target), "bar::baz::quux");
}
}