substrate_data/model/
reference.rs1use std::fmt;
5
6use crate::Atom;
7use crate::typed::TypedError;
8
9#[derive(Clone, Copy, PartialEq, Eq, Hash)]
13pub struct KindName(Atom);
14
15impl KindName {
16 pub fn new(name: &str) -> Result<KindName, TypedError> {
23 if Self::is_valid(name) {
24 Ok(KindName(Atom::new(name)))
25 } else {
26 Err(TypedError::BadKind {
27 kind: name.to_owned(),
28 })
29 }
30 }
31
32 #[must_use]
34 pub fn declared(name: &'static str) -> KindName {
35 debug_assert!(Self::is_valid(name), "`{name}` isn't a kind");
36 KindName(Atom::new(name))
37 }
38
39 #[must_use]
42 pub const fn is_valid(name: &str) -> bool {
43 let b = name.as_bytes();
44 if b.is_empty() || !b[0].is_ascii_lowercase() {
45 return false;
46 }
47 let mut i = 1;
48 while i < b.len() {
49 let c = b[i];
50 if !(c.is_ascii_lowercase() || c.is_ascii_digit() || c == b'_') {
51 return false;
52 }
53 i += 1;
54 }
55 true
56 }
57
58 #[must_use]
60 pub fn as_str(self) -> &'static str {
61 self.0.as_str()
62 }
63
64 #[must_use]
66 pub fn atom(self) -> Atom {
67 self.0
68 }
69}
70
71impl fmt::Debug for KindName {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 write!(f, "KindName({:?})", self.as_str())
74 }
75}
76
77impl fmt::Display for KindName {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 f.write_str(self.as_str())
80 }
81}
82
83impl PartialOrd for KindName {
84 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
85 Some(self.cmp(other))
86 }
87}
88
89impl Ord for KindName {
90 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
92 self.as_str().cmp(other.as_str())
93 }
94}
95
96impl PartialEq<str> for KindName {
97 fn eq(&self, other: &str) -> bool {
98 self.as_str() == other
99 }
100}
101
102impl PartialEq<&str> for KindName {
103 fn eq(&self, other: &&str) -> bool {
104 self.as_str() == *other
105 }
106}
107
108#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
112pub struct RefKey(Box<str>);
113
114impl RefKey {
115 pub fn new(id: &str) -> Result<RefKey, TypedError> {
121 if Self::is_valid(id) {
122 Ok(RefKey(id.into()))
123 } else {
124 Err(TypedError::BadId {
125 kind: None,
126 id: id.to_owned(),
127 })
128 }
129 }
130
131 #[must_use]
133 pub fn is_valid(id: &str) -> bool {
134 !id.is_empty() && !id.chars().any(|c| c.is_whitespace() || c.is_control())
135 }
136
137 pub(crate) fn spelled(id: &str) -> RefKey {
139 RefKey(id.into())
140 }
141
142 #[must_use]
144 pub fn as_str(&self) -> &str {
145 &self.0
146 }
147}
148
149impl fmt::Debug for RefKey {
150 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151 write!(f, "RefKey({:?})", &*self.0)
152 }
153}
154
155impl fmt::Display for RefKey {
156 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157 f.write_str(&self.0)
158 }
159}
160
161impl PartialEq<str> for RefKey {
162 fn eq(&self, other: &str) -> bool {
163 &*self.0 == other
164 }
165}
166
167impl PartialEq<&str> for RefKey {
168 fn eq(&self, other: &&str) -> bool {
169 &*self.0 == *other
170 }
171}
172
173impl std::ops::Deref for KindName {
174 type Target = str;
175 fn deref(&self) -> &str {
176 self.as_str()
177 }
178}
179
180impl AsRef<str> for KindName {
181 fn as_ref(&self) -> &str {
182 self.as_str()
183 }
184}
185
186impl PartialEq<String> for KindName {
187 fn eq(&self, other: &String) -> bool {
188 self.as_str() == other
189 }
190}
191
192impl std::ops::Deref for RefKey {
193 type Target = str;
194 fn deref(&self) -> &str {
195 &self.0
196 }
197}
198
199impl AsRef<str> for RefKey {
200 fn as_ref(&self) -> &str {
201 &self.0
202 }
203}
204
205impl std::borrow::Borrow<str> for RefKey {
207 fn borrow(&self) -> &str {
208 &self.0
209 }
210}
211
212impl PartialEq<String> for RefKey {
213 fn eq(&self, other: &String) -> bool {
214 &*self.0 == other
215 }
216}
217
218impl PartialEq<RefKey> for String {
219 fn eq(&self, other: &RefKey) -> bool {
220 self.as_str() == &*other.0
221 }
222}
223
224impl PartialEq<RefKey> for str {
225 fn eq(&self, other: &RefKey) -> bool {
226 self == &*other.0
227 }
228}