roussillon_type_system/
identity.rs

1//! A namespaced [Identifier] for named types like [crate::types::typedef::Enumeration] and [crate::types::typedef::Structure].
2//!
3//! The [Identified] trait helps to get information about the [Identifier] of a type. 
4
5use std::collections::HashMap;
6use std::fmt::{Display, Formatter};
7use std::hash::{Hash, Hasher};
8
9/// An identifier with a namespace.
10#[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/// A label to identify fields or members.
54#[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}