Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-ops/src/chunked_array/strings/pad.rs
6939 views
1
use std::fmt::Write;
2
3
use polars_core::prelude::arity::broadcast_binary_elementwise;
4
use polars_core::prelude::{StringChunked, UInt64Chunked};
5
6
fn pad_fn<'a>(
7
s: Option<&'a str>,
8
length: Option<u64>,
9
buf: &mut String,
10
fill_char: char,
11
pad_start: bool,
12
) -> Option<&'a str> {
13
if let (Some(s), Some(length)) = (s, length) {
14
let length = length as usize;
15
let n_chars = s.chars().count();
16
if length <= n_chars {
17
return Some(s);
18
}
19
let padding = length - n_chars;
20
buf.clear();
21
if !pad_start {
22
buf.push_str(s);
23
}
24
for _ in 0..padding {
25
buf.push(fill_char)
26
}
27
if pad_start {
28
buf.push_str(s);
29
}
30
// extend lifetime
31
// lifetime is bound to 'a
32
let slice = buf.as_str();
33
Some(unsafe { std::mem::transmute::<&str, &'a str>(slice) })
34
} else {
35
None
36
}
37
}
38
39
fn zfill_fn<'a>(s: Option<&'a str>, length: Option<u64>, buf: &mut String) -> Option<&'a str> {
40
if let (Some(s), Some(length)) = (s, length) {
41
let s_len = s.len();
42
let length = length as usize;
43
if length <= s_len {
44
return Some(s);
45
}
46
buf.clear();
47
let length = length - s_len;
48
if let Some(stripped) = s.strip_prefix('-') {
49
write!(buf, "-{:0length$}{stripped}", 0,).unwrap();
50
} else if let Some(stripped) = s.strip_prefix('+') {
51
write!(buf, "+{:0length$}{stripped}", 0,).unwrap();
52
} else {
53
write!(buf, "{:0length$}{s}", 0,).unwrap();
54
};
55
// extend lifetime
56
// lifetime is bound to 'a
57
let slice = buf.as_str();
58
Some(unsafe { std::mem::transmute::<&str, &'a str>(slice) })
59
} else {
60
None
61
}
62
}
63
64
pub(super) fn zfill<'a>(ca: &'a StringChunked, length: &'a UInt64Chunked) -> StringChunked {
65
// amortize allocation
66
let mut buf = String::new();
67
fn infer<F: for<'a> FnMut(Option<&'a str>, Option<u64>) -> Option<&'a str>>(f: F) -> F where {
68
f
69
}
70
broadcast_binary_elementwise(
71
ca,
72
length,
73
infer(|opt_s, opt_len| zfill_fn(opt_s, opt_len, &mut buf)),
74
)
75
}
76
77
pub(super) fn pad_start<'a>(
78
ca: &'a StringChunked,
79
length: &'a UInt64Chunked,
80
fill_char: char,
81
) -> StringChunked {
82
// amortize allocation
83
let mut buf = String::new();
84
fn infer<F: for<'a> FnMut(Option<&'a str>, Option<u64>) -> Option<&'a str>>(f: F) -> F where {
85
f
86
}
87
broadcast_binary_elementwise(
88
ca,
89
length,
90
infer(|opt_s, opt_len| pad_fn(opt_s, opt_len, &mut buf, fill_char, true)),
91
)
92
}
93
94
pub(super) fn pad_end<'a>(
95
ca: &'a StringChunked,
96
length: &'a UInt64Chunked,
97
fill_char: char,
98
) -> StringChunked {
99
// amortize allocation
100
let mut buf = String::new();
101
fn infer<F: for<'a> FnMut(Option<&'a str>, Option<u64>) -> Option<&'a str>>(f: F) -> F where {
102
f
103
}
104
broadcast_binary_elementwise(
105
ca,
106
length,
107
infer(|opt_s, opt_len| pad_fn(opt_s, opt_len, &mut buf, fill_char, false)),
108
)
109
}
110
111