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