60 lines
1.5 KiB
Rust
60 lines
1.5 KiB
Rust
|
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<ScopeSegment>,
|
||
|
}
|
||
|
|
||
|
impl Fqsn {
|
||
|
pub fn from_scope_stack(scopes: &[ScopeSegment], new_name: Rc<String>) -> 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<String> {
|
||
|
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<String>),
|
||
|
}
|
||
|
|
||
|
impl fmt::Display for ScopeSegment {
|
||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||
|
let ScopeSegment::Name(name) = self;
|
||
|
write!(f, "{}", name)
|
||
|
}
|
||
|
}
|