polars_utils/
pl_str.rs

1#[macro_export]
2macro_rules! format_pl_smallstr {
3    ($($arg:tt)*) => {{
4        use std::fmt::Write;
5
6        let mut string = $crate::pl_str::PlSmallStr::EMPTY;
7        write!(string, $($arg)*).unwrap();
8        string
9    }}
10}
11
12type Inner = compact_str::CompactString;
13
14/// String type that inlines small strings.
15#[derive(Clone, Eq, Hash, PartialOrd, Ord)]
16#[cfg_attr(
17    feature = "serde",
18    derive(serde::Serialize, serde::Deserialize),
19    serde(transparent)
20)]
21pub struct PlSmallStr(Inner);
22
23impl PlSmallStr {
24    pub const EMPTY: Self = Self::from_static("");
25    pub const EMPTY_REF: &'static Self = &Self::from_static("");
26
27    #[inline(always)]
28    pub const fn from_static(s: &'static str) -> Self {
29        Self(Inner::const_new(s))
30    }
31
32    #[inline(always)]
33    #[allow(clippy::should_implement_trait)]
34    pub fn from_str(s: &str) -> Self {
35        Self(Inner::from(s))
36    }
37
38    #[inline(always)]
39    pub fn from_string(s: String) -> Self {
40        Self(Inner::from(s))
41    }
42
43    #[inline(always)]
44    pub fn as_str(&self) -> &str {
45        self.0.as_str()
46    }
47
48    #[inline(always)]
49    pub fn into_string(self) -> String {
50        self.0.into_string()
51    }
52}
53
54impl Default for PlSmallStr {
55    #[inline(always)]
56    fn default() -> Self {
57        Self::EMPTY
58    }
59}
60
61// AsRef, Deref and Borrow impls to &str
62
63impl AsRef<str> for PlSmallStr {
64    #[inline(always)]
65    fn as_ref(&self) -> &str {
66        self.as_str()
67    }
68}
69
70impl core::ops::Deref for PlSmallStr {
71    type Target = str;
72
73    #[inline(always)]
74    fn deref(&self) -> &Self::Target {
75        self.as_str()
76    }
77}
78
79impl core::borrow::Borrow<str> for PlSmallStr {
80    #[inline(always)]
81    fn borrow(&self) -> &str {
82        self.as_str()
83    }
84}
85
86// AsRef impls for other types
87
88impl AsRef<std::path::Path> for PlSmallStr {
89    #[inline(always)]
90    fn as_ref(&self) -> &std::path::Path {
91        self.as_str().as_ref()
92    }
93}
94
95impl AsRef<[u8]> for PlSmallStr {
96    #[inline(always)]
97    fn as_ref(&self) -> &[u8] {
98        self.as_str().as_bytes()
99    }
100}
101
102impl AsRef<std::ffi::OsStr> for PlSmallStr {
103    #[inline(always)]
104    fn as_ref(&self) -> &std::ffi::OsStr {
105        self.as_str().as_ref()
106    }
107}
108
109// From impls
110
111impl From<&str> for PlSmallStr {
112    #[inline(always)]
113    fn from(value: &str) -> Self {
114        Self::from_str(value)
115    }
116}
117
118impl From<String> for PlSmallStr {
119    #[inline(always)]
120    fn from(value: String) -> Self {
121        Self::from_string(value)
122    }
123}
124
125impl From<&String> for PlSmallStr {
126    #[inline(always)]
127    fn from(value: &String) -> Self {
128        Self::from_str(value.as_str())
129    }
130}
131
132impl From<Inner> for PlSmallStr {
133    #[inline(always)]
134    fn from(value: Inner) -> Self {
135        Self(value)
136    }
137}
138
139// FromIterator impls
140
141impl FromIterator<PlSmallStr> for PlSmallStr {
142    #[inline(always)]
143    fn from_iter<T: IntoIterator<Item = PlSmallStr>>(iter: T) -> Self {
144        Self(Inner::from_iter(iter.into_iter().map(|x| x.0)))
145    }
146}
147
148impl<'a> FromIterator<&'a PlSmallStr> for PlSmallStr {
149    #[inline(always)]
150    fn from_iter<T: IntoIterator<Item = &'a PlSmallStr>>(iter: T) -> Self {
151        Self(Inner::from_iter(iter.into_iter().map(|x| x.as_str())))
152    }
153}
154
155impl FromIterator<char> for PlSmallStr {
156    #[inline(always)]
157    fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> PlSmallStr {
158        Self(Inner::from_iter(iter))
159    }
160}
161
162impl<'a> FromIterator<&'a char> for PlSmallStr {
163    #[inline(always)]
164    fn from_iter<I: IntoIterator<Item = &'a char>>(iter: I) -> PlSmallStr {
165        Self(Inner::from_iter(iter))
166    }
167}
168
169impl<'a> FromIterator<&'a str> for PlSmallStr {
170    #[inline(always)]
171    fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> PlSmallStr {
172        Self(Inner::from_iter(iter))
173    }
174}
175
176impl FromIterator<String> for PlSmallStr {
177    #[inline(always)]
178    fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> PlSmallStr {
179        Self(Inner::from_iter(iter))
180    }
181}
182
183impl FromIterator<Box<str>> for PlSmallStr {
184    #[inline(always)]
185    fn from_iter<I: IntoIterator<Item = Box<str>>>(iter: I) -> PlSmallStr {
186        Self(Inner::from_iter(iter))
187    }
188}
189
190impl<'a> FromIterator<std::borrow::Cow<'a, str>> for PlSmallStr {
191    #[inline(always)]
192    fn from_iter<I: IntoIterator<Item = std::borrow::Cow<'a, str>>>(iter: I) -> PlSmallStr {
193        Self(Inner::from_iter(iter))
194    }
195}
196
197// PartialEq impls
198
199impl<T> PartialEq<T> for PlSmallStr
200where
201    T: AsRef<str> + ?Sized,
202{
203    #[inline(always)]
204    fn eq(&self, other: &T) -> bool {
205        self.as_str() == other.as_ref()
206    }
207}
208
209impl PartialEq<PlSmallStr> for &str {
210    #[inline(always)]
211    fn eq(&self, other: &PlSmallStr) -> bool {
212        *self == other.as_str()
213    }
214}
215
216impl PartialEq<PlSmallStr> for String {
217    #[inline(always)]
218    fn eq(&self, other: &PlSmallStr) -> bool {
219        self.as_str() == other.as_str()
220    }
221}
222
223// Write
224
225impl core::fmt::Write for PlSmallStr {
226    #[inline(always)]
227    fn write_char(&mut self, c: char) -> std::fmt::Result {
228        self.0.write_char(c)
229    }
230
231    #[inline(always)]
232    fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> std::fmt::Result {
233        self.0.write_fmt(args)
234    }
235
236    #[inline(always)]
237    fn write_str(&mut self, s: &str) -> std::fmt::Result {
238        self.0.write_str(s)
239    }
240}
241
242// Debug, Display
243
244impl core::fmt::Debug for PlSmallStr {
245    #[inline(always)]
246    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
247        self.as_str().fmt(f)
248    }
249}
250
251impl core::fmt::Display for PlSmallStr {
252    #[inline(always)]
253    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
254        self.as_str().fmt(f)
255    }
256}