use std::{fmt, rc::Rc}; /// Fully-qualified symbol name #[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] pub struct Fqsn { //TODO Fqsn's need to be cheaply cloneable pub scopes: Vec, } impl Fqsn { pub fn from_scope_stack(scopes: &[ScopeSegment], new_name: Rc) -> Self { let mut v = Vec::new(); for s in scopes { v.push(s.clone()); } v.push(ScopeSegment::Name(new_name)); Fqsn { scopes: v } } #[allow(dead_code)] pub fn from_strs(strs: &[&str]) -> Fqsn { let mut scopes = vec![]; for s in strs { scopes.push(ScopeSegment::Name(Rc::new(s.to_string()))); } Fqsn { scopes } } pub fn last_elem(&self) -> Rc { let ScopeSegment::Name(name) = self.scopes.last().unwrap(); name.clone() } } impl fmt::Display for Fqsn { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let delim = "::"; let Fqsn { scopes } = self; write!(f, "FQSN<{}", scopes[0])?; for item in scopes[1..].iter() { write!(f, "{}{}", delim, item)?; } write!(f, ">") } } //TODO eventually this should use ItemId's to avoid String-cloning /// One segment within a scope. #[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] pub enum ScopeSegment { Name(Rc), } impl fmt::Display for ScopeSegment { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let ScopeSegment::Name(name) = self; write!(f, "{}", name) } }