nu_utils/strings/
unique.rs1use std::{
2 borrow::Borrow,
3 fmt::{Arguments, Debug, Display},
4 hash::Hash,
5 ops::Deref,
6};
7
8use serde::{Deserialize, Serialize};
9
10pub struct UniqueString(byteyarn::Yarn);
41
42const _: () = const {
43 assert!(size_of::<UniqueString>() == size_of::<[usize; 2]>());
44 assert!(size_of::<UniqueString>() == size_of::<Option<UniqueString>>());
45};
46
47impl UniqueString {
48 #[inline]
50 pub fn as_str(&self) -> &str {
51 self.0.as_str()
52 }
53
54 #[inline]
56 pub fn as_bytes(&self) -> &[u8] {
57 self.0.as_bytes()
58 }
59
60 #[inline]
62 pub fn len(&self) -> usize {
63 self.0.len()
64 }
65
66 #[inline]
68 pub fn is_empty(&self) -> bool {
69 self.0.is_empty()
70 }
71
72 #[inline]
74 pub fn from_string(string: String) -> Self {
75 Self(byteyarn::Yarn::from_string(string))
76 }
77
78 #[inline]
83 pub fn from_static_str(string: &'static str) -> Self {
84 Self(byteyarn::Yarn::from_static(string))
85 }
86
87 #[inline]
93 pub fn from_fmt(arguments: Arguments) -> Self {
94 Self(byteyarn::Yarn::from_fmt(arguments))
95 }
96}
97
98impl AsRef<str> for UniqueString {
99 #[inline]
100 fn as_ref(&self) -> &str {
101 self.as_str()
102 }
103}
104
105impl Borrow<str> for UniqueString {
106 #[inline]
107 fn borrow(&self) -> &str {
108 self.as_str()
109 }
110}
111
112impl Clone for UniqueString {
113 #[inline]
114 fn clone(&self) -> Self {
115 Self(self.0.clone())
116 }
117}
118
119impl Debug for UniqueString {
120 #[inline]
121 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122 Debug::fmt(&self.0, f)
123 }
124}
125
126impl Default for UniqueString {
127 #[inline]
128 fn default() -> Self {
129 Self(Default::default())
130 }
131}
132
133impl Deref for UniqueString {
134 type Target = str;
135
136 #[inline]
137 fn deref(&self) -> &Self::Target {
138 self.as_str()
139 }
140}
141
142impl Display for UniqueString {
143 #[inline]
144 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145 Display::fmt(&self.0, f)
146 }
147}
148
149impl Eq for UniqueString {}
150
151impl From<String> for UniqueString {
152 #[inline]
153 fn from(string: String) -> Self {
154 Self::from_string(string)
155 }
156}
157
158impl From<&'static str> for UniqueString {
159 #[inline]
160 fn from(string: &'static str) -> Self {
161 Self::from_static_str(string)
162 }
163}
164
165impl Hash for UniqueString {
166 #[inline]
167 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
168 self.0.hash(state);
169 }
170}
171
172impl Ord for UniqueString {
173 #[inline]
174 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
175 self.0.cmp(&other.0)
176 }
177}
178
179impl PartialEq for UniqueString {
180 #[inline]
181 fn eq(&self, other: &Self) -> bool {
182 self.0 == other.0
183 }
184}
185
186impl PartialOrd for UniqueString {
187 #[inline]
188 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
189 Some(self.cmp(other))
190 }
191}
192
193impl Serialize for UniqueString {
194 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
195 where
196 S: serde::Serializer,
197 {
198 self.0.serialize(serializer)
199 }
200}
201
202impl<'de> Deserialize<'de> for UniqueString {
203 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
204 where
205 D: serde::Deserializer<'de>,
206 {
207 let s = String::deserialize(deserializer)?;
208 Ok(Self::from_string(s))
209 }
210}
211
212#[macro_export]
217macro_rules! uformat {
218 ($fmt:expr) => {
219 $crate::strings::UniqueString::from_fmt(::std::format_args!($fmt))
220 };
221
222 ($fmt:expr, $($args:tt)*) => {
223 $crate::strings::UniqueString::from_fmt(::std::format_args!($fmt, $($args)*))
224 };
225}
226
227#[cfg(test)]
228mod tests {
229 use super::*;
230
231 #[test]
232 fn macro_works() {
233 assert!(uformat!("").is_empty());
234 assert_eq!(
235 uformat!("Hello World"),
236 UniqueString::from_static_str("Hello World")
237 );
238 assert_eq!(
239 uformat!("Hello {}", "World"),
240 UniqueString::from_static_str("Hello World")
241 );
242 }
243}