Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-utils/src/pl_str.rs
8424 views
1
use std::borrow::Cow;
2
3
pub use super::pl_ref_str::PlRefStr;
4
use crate::relaxed_cell::RelaxedCell;
5
6
#[macro_export]
7
macro_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
17
type Inner = compact_str::CompactString;
18
19
/// String type that inlines small strings.
20
#[derive(Clone, Eq, Hash, PartialOrd, Ord)]
21
#[cfg_attr(
22
feature = "serde",
23
derive(serde::Serialize, serde::Deserialize),
24
serde(transparent)
25
)]
26
pub struct PlSmallStr(Inner);
27
28
#[cfg(feature = "dsl-schema")]
29
impl 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
45
impl 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)] // This is faster.
77
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
87
impl Default for PlSmallStr {
88
#[inline(always)]
89
fn default() -> Self {
90
Self::EMPTY
91
}
92
}
93
94
// AsRef, Deref and Borrow impls to &str
95
96
impl AsRef<str> for PlSmallStr {
97
#[inline(always)]
98
fn as_ref(&self) -> &str {
99
self.as_str()
100
}
101
}
102
103
impl 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
112
impl 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
119
impl core::borrow::Borrow<str> for PlSmallStr {
120
#[inline(always)]
121
fn borrow(&self) -> &str {
122
self.as_str()
123
}
124
}
125
126
// AsRef impls for other types
127
128
impl 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
135
impl AsRef<[u8]> for PlSmallStr {
136
#[inline(always)]
137
fn as_ref(&self) -> &[u8] {
138
self.as_bytes()
139
}
140
}
141
142
impl 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
149
// From impls
150
151
impl From<&str> for PlSmallStr {
152
#[inline(always)]
153
fn from(value: &str) -> Self {
154
Self::from_str(value)
155
}
156
}
157
158
impl From<String> for PlSmallStr {
159
#[inline(always)]
160
fn from(value: String) -> Self {
161
Self::from_string(value)
162
}
163
}
164
165
impl From<PlSmallStr> for String {
166
#[inline(always)]
167
fn from(value: PlSmallStr) -> Self {
168
value.to_string()
169
}
170
}
171
172
impl From<Cow<'_, str>> for PlSmallStr {
173
#[inline(always)]
174
fn from(value: Cow<str>) -> Self {
175
Self(Inner::from(value))
176
}
177
}
178
179
impl From<&String> for PlSmallStr {
180
#[inline(always)]
181
fn from(value: &String) -> Self {
182
Self::from_str(value.as_str())
183
}
184
}
185
186
impl From<Inner> for PlSmallStr {
187
#[inline(always)]
188
fn from(value: Inner) -> Self {
189
Self(value)
190
}
191
}
192
193
// FromIterator impls
194
195
impl 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
202
impl<'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
209
impl 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
216
impl<'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
223
impl<'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
230
impl 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
237
impl 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
244
impl<'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
251
// PartialEq impls
252
253
impl<T> PartialEq<T> for PlSmallStr
254
where
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
263
impl PartialEq<PlSmallStr> for &str {
264
#[inline(always)]
265
fn eq(&self, other: &PlSmallStr) -> bool {
266
*self == other.as_str()
267
}
268
}
269
270
impl PartialEq<PlSmallStr> for String {
271
#[inline(always)]
272
fn eq(&self, other: &PlSmallStr) -> bool {
273
self.as_str() == other.as_str()
274
}
275
}
276
277
// Write
278
279
impl 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
296
// Debug, Display
297
298
impl 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
305
impl 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
312
pub 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
}
317
318