nu_utils/strings/
shared.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 SharedString(lean_string::LeanString);
42
43const _: () = const {
44 assert!(size_of::<SharedString>() == size_of::<[usize; 2]>());
45 assert!(size_of::<SharedString>() == size_of::<Option<SharedString>>());
46};
47
48impl SharedString {
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(lean_string::LeanString::from(string))
77 }
78
79 #[inline]
84 pub fn from_static_str(string: &'static str) -> Self {
85 Self(lean_string::LeanString::from_static_str(string))
86 }
87
88 #[inline]
94 pub fn from_fmt(arguments: Arguments) -> Self {
95 match arguments.as_str() {
96 Some(static_str) => Self::from_static_str(static_str),
97 None => Self::from_string(std::fmt::format(arguments)),
98 }
99 }
100}
101
102impl AsRef<str> for SharedString {
103 #[inline]
104 fn as_ref(&self) -> &str {
105 self.as_str()
106 }
107}
108
109impl Borrow<str> for SharedString {
110 #[inline]
111 fn borrow(&self) -> &str {
112 self.as_str()
113 }
114}
115
116impl Deref for SharedString {
117 type Target = str;
118
119 #[inline]
120 fn deref(&self) -> &Self::Target {
121 self.as_str()
122 }
123}
124
125impl Display for SharedString {
126 #[inline]
127 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128 Display::fmt(&self.0, f)
129 }
130}
131
132impl Eq for SharedString {}
133
134impl From<String> for SharedString {
135 #[inline]
136 fn from(string: String) -> Self {
137 Self::from_string(string)
138 }
139}
140
141impl From<&'static str> for SharedString {
142 #[inline]
143 fn from(string: &'static str) -> Self {
144 Self::from_static_str(string)
145 }
146}
147
148impl Hash for SharedString {
149 #[inline]
150 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
151 self.0.hash(state);
152 }
153}
154
155impl Ord for SharedString {
156 #[inline]
157 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
158 self.0.cmp(&other.0)
159 }
160}
161
162impl PartialEq for SharedString {
163 #[inline]
164 fn eq(&self, other: &Self) -> bool {
165 self.0 == other.0
166 }
167}
168
169impl PartialOrd for SharedString {
170 #[inline]
171 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
172 Some(self.cmp(other))
173 }
174}
175
176impl Serialize for SharedString {
177 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
178 where
179 S: serde::Serializer,
180 {
181 self.0.serialize(serializer)
182 }
183}
184
185impl<'de> Deserialize<'de> for SharedString {
186 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
187 where
188 D: serde::Deserializer<'de>,
189 {
190 Ok(Self(lean_string::LeanString::deserialize(deserializer)?))
191 }
192}
193
194#[macro_export]
199macro_rules! sformat {
200 ($fmt:expr) => {
201 $crate::strings::SharedString::from_fmt(::std::format_args!($fmt))
202 };
203
204 ($fmt:expr, $($args:tt)*) => {
205 $crate::strings::SharedString::from_fmt(::std::format_args!($fmt, $($args)*))
206 };
207}
208
209#[cfg(test)]
210mod tests {
211 use super::*;
212
213 #[test]
214 fn macro_works() {
215 assert!(sformat!("").is_empty());
216 assert_eq!(
217 sformat!("Hello World"),
218 SharedString::from_static_str("Hello World")
219 );
220 assert_eq!(
221 sformat!("Hello {}", "World"),
222 SharedString::from_static_str("Hello World")
223 );
224 }
225}