Path: blob/main/crates/polars-ops/src/chunked_array/strings/pad.rs
6939 views
use std::fmt::Write;12use polars_core::prelude::arity::broadcast_binary_elementwise;3use polars_core::prelude::{StringChunked, UInt64Chunked};45fn pad_fn<'a>(6s: Option<&'a str>,7length: Option<u64>,8buf: &mut String,9fill_char: char,10pad_start: bool,11) -> Option<&'a str> {12if let (Some(s), Some(length)) = (s, length) {13let length = length as usize;14let n_chars = s.chars().count();15if length <= n_chars {16return Some(s);17}18let padding = length - n_chars;19buf.clear();20if !pad_start {21buf.push_str(s);22}23for _ in 0..padding {24buf.push(fill_char)25}26if pad_start {27buf.push_str(s);28}29// extend lifetime30// lifetime is bound to 'a31let slice = buf.as_str();32Some(unsafe { std::mem::transmute::<&str, &'a str>(slice) })33} else {34None35}36}3738fn zfill_fn<'a>(s: Option<&'a str>, length: Option<u64>, buf: &mut String) -> Option<&'a str> {39if let (Some(s), Some(length)) = (s, length) {40let s_len = s.len();41let length = length as usize;42if length <= s_len {43return Some(s);44}45buf.clear();46let length = length - s_len;47if let Some(stripped) = s.strip_prefix('-') {48write!(buf, "-{:0length$}{stripped}", 0,).unwrap();49} else if let Some(stripped) = s.strip_prefix('+') {50write!(buf, "+{:0length$}{stripped}", 0,).unwrap();51} else {52write!(buf, "{:0length$}{s}", 0,).unwrap();53};54// extend lifetime55// lifetime is bound to 'a56let slice = buf.as_str();57Some(unsafe { std::mem::transmute::<&str, &'a str>(slice) })58} else {59None60}61}6263pub(super) fn zfill<'a>(ca: &'a StringChunked, length: &'a UInt64Chunked) -> StringChunked {64// amortize allocation65let mut buf = String::new();66fn infer<F: for<'a> FnMut(Option<&'a str>, Option<u64>) -> Option<&'a str>>(f: F) -> F where {67f68}69broadcast_binary_elementwise(70ca,71length,72infer(|opt_s, opt_len| zfill_fn(opt_s, opt_len, &mut buf)),73)74}7576pub(super) fn pad_start<'a>(77ca: &'a StringChunked,78length: &'a UInt64Chunked,79fill_char: char,80) -> StringChunked {81// amortize allocation82let mut buf = String::new();83fn infer<F: for<'a> FnMut(Option<&'a str>, Option<u64>) -> Option<&'a str>>(f: F) -> F where {84f85}86broadcast_binary_elementwise(87ca,88length,89infer(|opt_s, opt_len| pad_fn(opt_s, opt_len, &mut buf, fill_char, true)),90)91}9293pub(super) fn pad_end<'a>(94ca: &'a StringChunked,95length: &'a UInt64Chunked,96fill_char: char,97) -> StringChunked {98// amortize allocation99let mut buf = String::new();100fn infer<F: for<'a> FnMut(Option<&'a str>, Option<u64>) -> Option<&'a str>>(f: F) -> F where {101f102}103broadcast_binary_elementwise(104ca,105length,106infer(|opt_s, opt_len| pad_fn(opt_s, opt_len, &mut buf, fill_char, false)),107)108}109110111