roussillon_type_system/
identity.rs1use std::collections::HashMap;
6use std::fmt::{Display, Formatter};
7use std::hash::{Hash, Hasher};
8
9#[derive(Clone, Eq, PartialEq, Debug)]
11pub struct Identifier {
12 pub space: String,
13 pub name: String,
14}
15
16impl Identifier {
17 pub fn new(from: &str) -> Self {
18 from.split_once('/')
19 .map(|(space, name)| Identifier { space: space.to_string(), name: name.to_string() })
20 .unwrap_or_else(|| Identifier { space: String::new(), name: from.to_string() })
21 }
22 pub fn core(name: &str) -> Self {
23 Self {
24 space: "Core".to_string(),
25 name: name.to_string(),
26 }
27 }
28}
29
30impl Display for Identifier {
31 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
32 write!(f, "{}",
33 if self.space.is_empty() {
34 self.name.to_string()
35 } else { format!("{}/{}", self.space, self.name) },
36 )
37 }
38}
39
40pub trait Identified {
41 fn identifier(&self) -> Identifier;
42 fn name(&self) -> String { self.identifier().name }
43 fn space(&self) -> String { self.identifier().space }
44 fn fully_qualified_name(&self, current_namespace: String) -> String {
45 if self.space().is_empty() {
46 format!("{}/{}", current_namespace, self.identifier())
47 } else {
48 self.identifier().to_string()
49 }
50 }
51}
52
53#[derive(Clone, Eq, PartialEq, Debug)]
55pub struct Label(String);
56
57impl Label {
58 pub fn new(name: &str) -> Self {
59 Label(name.to_string())
60 }
61}
62
63impl Display for Label {
64 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) }
65}
66
67impl Hash for Label {
68 fn hash<H: Hasher>(&self, state: &mut H) { state.write(self.0.as_bytes()) }
69}
70
71pub trait Labelled<T> {
72 fn labelled(&self, label: &Label) -> Option<T>;
73}
74
75#[derive(Clone, Debug)]
76pub struct LabelBank(HashMap<Label, usize>);
77
78impl LabelBank {
79 pub fn from(labels: &[&str]) -> Self {
80 let mut label_bank = HashMap::new();
81 for (index, label) in labels.iter().enumerate() {
82 label_bank.insert(Label::new(label), index);
83 }
84 Self(label_bank)
85 }
86}
87
88impl Labelled<usize> for LabelBank {
89
90 fn labelled(&self, label: &Label) -> Option<usize> { self.0.get(label).cloned() }
91}