Skip to main content

spacetimedb_sats/
raw_identifier.rs

1use crate::algebraic_type::AlgebraicType;
2use crate::{impl_deserialize, impl_serialize, impl_st};
3use core::borrow::Borrow;
4use core::fmt;
5use core::ops::Deref;
6use lean_string::{LeanString, ToLeanString};
7
8/// A not-yet-validated identifier.
9#[derive(Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
10pub struct RawIdentifier(pub(crate) LeanString);
11
12impl_st!([] RawIdentifier, _ts => AlgebraicType::String);
13impl_serialize!([] RawIdentifier, (self, ser) => ser.serialize_str(&self.0));
14impl_deserialize!([] RawIdentifier, de => LeanString::deserialize(de).map(Self));
15impl RawIdentifier {
16    /// Creates a new `RawIdentifier` from a string.
17    pub fn new(name: impl Into<LeanString>) -> Self {
18        Self(name.into())
19    }
20
21    pub fn into_inner(self) -> LeanString {
22        self.0
23    }
24}
25
26impl Deref for RawIdentifier {
27    type Target = str;
28
29    fn deref(&self) -> &Self::Target {
30        &self.0
31    }
32}
33
34impl AsRef<str> for RawIdentifier {
35    fn as_ref(&self) -> &str {
36        &self.0
37    }
38}
39
40impl Borrow<str> for RawIdentifier {
41    fn borrow(&self) -> &str {
42        &self.0
43    }
44}
45
46impl fmt::Debug for RawIdentifier {
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        fmt::Debug::fmt(&self.0, f)
49    }
50}
51
52impl fmt::Display for RawIdentifier {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        fmt::Display::fmt(&self.0, f)
55    }
56}
57
58impl From<&'static str> for RawIdentifier {
59    fn from(s: &'static str) -> Self {
60        RawIdentifier(LeanString::from_static_str(s))
61    }
62}
63
64impl From<String> for RawIdentifier {
65    fn from(s: String) -> Self {
66        RawIdentifier(s.to_lean_string())
67    }
68}
69
70/// A not-yet-validated, dot-separated name, e.g. `"lib.library_table"`.
71///
72/// This is the raw counterpart of `spacetimedb_schema`'s `NamespacedIdentifier`,
73/// in the same way that [`RawIdentifier`] is the raw counterpart of `Identifier`.
74///
75/// The distinction matters: a [`RawIdentifier`] can be validated into a single
76/// `Identifier`, but a name containing `.` never can be, since `.` is not a legal
77/// identifier character. Names that may carry a namespace therefore use this type
78/// rather than [`RawIdentifier`], so that the two cannot be confused.
79#[derive(Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
80pub struct RawNamespacedIdentifier(LeanString);
81
82impl_st!([] RawNamespacedIdentifier, _ts => AlgebraicType::String);
83impl_serialize!([] RawNamespacedIdentifier, (self, ser) => ser.serialize_str(&self.0));
84impl_deserialize!([] RawNamespacedIdentifier, de => LeanString::deserialize(de).map(Self));
85
86impl RawNamespacedIdentifier {
87    /// Creates a new `RawNamespacedIdentifier` from a string.
88    pub fn new(name: impl Into<LeanString>) -> Self {
89        Self(name.into())
90    }
91
92    /// The dot-separated segments of this name, in order.
93    ///
94    /// Always yields at least one item; an empty name yields one empty segment.
95    pub fn segments(&self) -> impl Iterator<Item = &str> + Clone {
96        self.0.split('.')
97    }
98
99    /// The final segment, i.e. the name with any namespace prefix stripped.
100    ///
101    /// `"lib.sessions_id_idx"` yields `"sessions_id_idx"`; an un-namespaced name
102    /// yields itself.
103    pub fn local_name(&self) -> &str {
104        // `rsplit` on a non-empty pattern always yields at least one item.
105        self.0.rsplit('.').next().unwrap_or(&self.0)
106    }
107
108    /// Whether this name carries a namespace prefix.
109    pub fn is_namespaced(&self) -> bool {
110        self.0.contains('.')
111    }
112
113    pub fn into_inner(self) -> LeanString {
114        self.0
115    }
116}
117
118impl Deref for RawNamespacedIdentifier {
119    type Target = str;
120
121    fn deref(&self) -> &Self::Target {
122        &self.0
123    }
124}
125
126impl AsRef<str> for RawNamespacedIdentifier {
127    fn as_ref(&self) -> &str {
128        &self.0
129    }
130}
131
132impl Borrow<str> for RawNamespacedIdentifier {
133    fn borrow(&self) -> &str {
134        &self.0
135    }
136}
137
138impl fmt::Debug for RawNamespacedIdentifier {
139    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140        fmt::Debug::fmt(&self.0, f)
141    }
142}
143
144impl fmt::Display for RawNamespacedIdentifier {
145    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146        fmt::Display::fmt(&self.0, f)
147    }
148}
149
150impl From<RawIdentifier> for RawNamespacedIdentifier {
151    /// Every single identifier is a one-segment namespaced name.
152    fn from(id: RawIdentifier) -> Self {
153        Self(id.0)
154    }
155}
156
157impl From<&'static str> for RawNamespacedIdentifier {
158    fn from(s: &'static str) -> Self {
159        Self(LeanString::from_static_str(s))
160    }
161}
162
163impl From<String> for RawNamespacedIdentifier {
164    fn from(s: String) -> Self {
165        Self(s.to_lean_string())
166    }
167}