1use std::borrow::Cow;
2
3pub use super::pl_ref_str::PlRefStr;
4use crate::relaxed_cell::RelaxedCell;
5
6#[macro_export]
7macro_rules! format_pl_smallstr {
8 ($($arg:tt)*) => {{
9 use std::fmt::Write;
10
11 let mut string = $crate::pl_str::PlSmallStr::EMPTY;
12 write!(string, $($arg)*).unwrap();
13 string
14 }}
15}
16
17type Inner = compact_str::CompactString;
18
19#[derive(Clone, Eq, Hash, PartialOrd, Ord)]
21#[cfg_attr(
22 feature = "serde",
23 derive(serde::Serialize, serde::Deserialize),
24 serde(transparent)
25)]
26pub struct PlSmallStr(Inner);
27
28#[cfg(feature = "dsl-schema")]
29impl schemars::JsonSchema for PlSmallStr {
30 fn inline_schema() -> bool {
31 String::inline_schema()
32 }
33
34 fn schema_name() -> std::borrow::Cow<'static, str> {
35 String::schema_name()
36 }
37 fn schema_id() -> std::borrow::Cow<'static, str> {
38 String::schema_id()
39 }
40 fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
41 String::json_schema(generator)
42 }
43}
44
45impl PlSmallStr {
46 pub const EMPTY: Self = Self::from_static("");
47 pub const EMPTY_REF: &'static Self = &Self::from_static("");
48
49 #[inline(always)]
50 pub const fn from_static(s: &'static str) -> Self {
51 Self(Inner::const_new(s))
52 }
53
54 #[inline(always)]
55 #[allow(clippy::should_implement_trait)]
56 pub fn from_str(s: &str) -> Self {
57 Self(Inner::from(s))
58 }
59
60 #[inline(always)]
61 pub fn from_string(s: String) -> Self {
62 Self(Inner::from(s))
63 }
64
65 #[inline(always)]
66 pub fn as_str(&self) -> &str {
67 self.0.as_str()
68 }
69
70 #[inline(always)]
71 pub fn as_mut_str(&mut self) -> &mut str {
72 self.0.as_mut_str()
73 }
74
75 #[inline(always)]
76 #[allow(clippy::inherent_to_string_shadow_display)] pub fn to_string(&self) -> String {
78 self.0.as_str().to_owned()
79 }
80
81 #[inline(always)]
82 pub fn into_string(self) -> String {
83 self.0.into_string()
84 }
85}
86
87impl Default for PlSmallStr {
88 #[inline(always)]
89 fn default() -> Self {
90 Self::EMPTY
91 }
92}
93
94impl AsRef<str> for PlSmallStr {
97 #[inline(always)]
98 fn as_ref(&self) -> &str {
99 self.as_str()
100 }
101}
102
103impl core::ops::Deref for PlSmallStr {
104 type Target = str;
105
106 #[inline(always)]
107 fn deref(&self) -> &Self::Target {
108 self.as_str()
109 }
110}
111
112impl core::ops::DerefMut for PlSmallStr {
113 #[inline(always)]
114 fn deref_mut(&mut self) -> &mut Self::Target {
115 self.as_mut_str()
116 }
117}
118
119impl core::borrow::Borrow<str> for PlSmallStr {
120 #[inline(always)]
121 fn borrow(&self) -> &str {
122 self.as_str()
123 }
124}
125
126impl AsRef<std::path::Path> for PlSmallStr {
129 #[inline(always)]
130 fn as_ref(&self) -> &std::path::Path {
131 self.as_str().as_ref()
132 }
133}
134
135impl AsRef<[u8]> for PlSmallStr {
136 #[inline(always)]
137 fn as_ref(&self) -> &[u8] {
138 self.as_bytes()
139 }
140}
141
142impl AsRef<std::ffi::OsStr> for PlSmallStr {
143 #[inline(always)]
144 fn as_ref(&self) -> &std::ffi::OsStr {
145 self.as_str().as_ref()
146 }
147}
148
149impl From<&str> for PlSmallStr {
152 #[inline(always)]
153 fn from(value: &str) -> Self {
154 Self::from_str(value)
155 }
156}
157
158impl From<String> for PlSmallStr {
159 #[inline(always)]
160 fn from(value: String) -> Self {
161 Self::from_string(value)
162 }
163}
164
165impl From<PlSmallStr> for String {
166 #[inline(always)]
167 fn from(value: PlSmallStr) -> Self {
168 value.to_string()
169 }
170}
171
172impl From<Cow<'_, str>> for PlSmallStr {
173 #[inline(always)]
174 fn from(value: Cow<str>) -> Self {
175 Self(Inner::from(value))
176 }
177}
178
179impl From<&String> for PlSmallStr {
180 #[inline(always)]
181 fn from(value: &String) -> Self {
182 Self::from_str(value.as_str())
183 }
184}
185
186impl From<Inner> for PlSmallStr {
187 #[inline(always)]
188 fn from(value: Inner) -> Self {
189 Self(value)
190 }
191}
192
193impl FromIterator<PlSmallStr> for PlSmallStr {
196 #[inline(always)]
197 fn from_iter<T: IntoIterator<Item = PlSmallStr>>(iter: T) -> Self {
198 Self(Inner::from_iter(iter.into_iter().map(|x| x.0)))
199 }
200}
201
202impl<'a> FromIterator<&'a PlSmallStr> for PlSmallStr {
203 #[inline(always)]
204 fn from_iter<T: IntoIterator<Item = &'a PlSmallStr>>(iter: T) -> Self {
205 Self(Inner::from_iter(iter.into_iter().map(|x| x.as_str())))
206 }
207}
208
209impl FromIterator<char> for PlSmallStr {
210 #[inline(always)]
211 fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> PlSmallStr {
212 Self(Inner::from_iter(iter))
213 }
214}
215
216impl<'a> FromIterator<&'a char> for PlSmallStr {
217 #[inline(always)]
218 fn from_iter<I: IntoIterator<Item = &'a char>>(iter: I) -> PlSmallStr {
219 Self(Inner::from_iter(iter))
220 }
221}
222
223impl<'a> FromIterator<&'a str> for PlSmallStr {
224 #[inline(always)]
225 fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> PlSmallStr {
226 Self(Inner::from_iter(iter))
227 }
228}
229
230impl FromIterator<String> for PlSmallStr {
231 #[inline(always)]
232 fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> PlSmallStr {
233 Self(Inner::from_iter(iter))
234 }
235}
236
237impl FromIterator<Box<str>> for PlSmallStr {
238 #[inline(always)]
239 fn from_iter<I: IntoIterator<Item = Box<str>>>(iter: I) -> PlSmallStr {
240 Self(Inner::from_iter(iter))
241 }
242}
243
244impl<'a> FromIterator<std::borrow::Cow<'a, str>> for PlSmallStr {
245 #[inline(always)]
246 fn from_iter<I: IntoIterator<Item = std::borrow::Cow<'a, str>>>(iter: I) -> PlSmallStr {
247 Self(Inner::from_iter(iter))
248 }
249}
250
251impl<T> PartialEq<T> for PlSmallStr
254where
255 T: AsRef<str> + ?Sized,
256{
257 #[inline(always)]
258 fn eq(&self, other: &T) -> bool {
259 self.as_str() == other.as_ref()
260 }
261}
262
263impl PartialEq<PlSmallStr> for &str {
264 #[inline(always)]
265 fn eq(&self, other: &PlSmallStr) -> bool {
266 *self == other.as_str()
267 }
268}
269
270impl PartialEq<PlSmallStr> for String {
271 #[inline(always)]
272 fn eq(&self, other: &PlSmallStr) -> bool {
273 self.as_str() == other.as_str()
274 }
275}
276
277impl core::fmt::Write for PlSmallStr {
280 #[inline(always)]
281 fn write_char(&mut self, c: char) -> std::fmt::Result {
282 self.0.write_char(c)
283 }
284
285 #[inline(always)]
286 fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> std::fmt::Result {
287 self.0.write_fmt(args)
288 }
289
290 #[inline(always)]
291 fn write_str(&mut self, s: &str) -> std::fmt::Result {
292 self.0.write_str(s)
293 }
294}
295
296impl core::fmt::Debug for PlSmallStr {
299 #[inline(always)]
300 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
301 self.as_str().fmt(f)
302 }
303}
304
305impl core::fmt::Display for PlSmallStr {
306 #[inline(always)]
307 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
308 self.as_str().fmt(f)
309 }
310}
311
312pub fn unique_column_name() -> PlSmallStr {
313 static COUNTER: RelaxedCell<u64> = RelaxedCell::new_u64(0);
314 let idx = COUNTER.fetch_add(1);
315 format_pl_smallstr!("_POLARS_TMP_{idx}")
316}