(
string_array: V,
target_len: usize,
fill: &str,
)
| 244 | } |
| 245 | |
| 246 | fn rpad_scalar_unicode<'a, V: StringArrayType<'a> + Copy, T: OffsetSizeTrait>( |
| 247 | string_array: V, |
| 248 | target_len: usize, |
| 249 | fill: &str, |
| 250 | ) -> Result<ArrayRef> { |
| 251 | let fill_chars: Vec<char> = fill.chars().collect(); |
| 252 | |
| 253 | // With a scalar `target_len` and `fill`, we can precompute a padding buffer |
| 254 | // of `target_len` fill characters repeated cyclically. Because Unicode |
| 255 | // characters are variable-width, we build a byte-offset table to map from |
| 256 | // character count to the corresponding byte position in the padding buffer. |
| 257 | let (padding_buf, char_byte_offsets) = if !fill_chars.is_empty() { |
| 258 | let mut buf = String::new(); |
| 259 | let mut offsets = Vec::with_capacity(target_len + 1); |
| 260 | offsets.push(0usize); |
| 261 | for i in 0..target_len { |
| 262 | buf.push(fill_chars[i % fill_chars.len()]); |
| 263 | offsets.push(buf.len()); |
| 264 | } |
| 265 | (buf, offsets) |
| 266 | } else { |
| 267 | (String::new(), vec![0]) |
| 268 | }; |
| 269 | |
| 270 | // Each output row is `target_len` chars; multiply by 4 (max UTF-8 bytes |
| 271 | // per char) for an upper bound in bytes. |
| 272 | let data_capacity = string_array.len().saturating_mul(target_len * 4); |
| 273 | let mut builder = |
| 274 | GenericStringBuilder::<T>::with_capacity(string_array.len(), data_capacity); |
| 275 | |
| 276 | for maybe_string in string_array.iter() { |
| 277 | match maybe_string { |
| 278 | Some(string) => match char_count_or_boundary(string, target_len) { |
| 279 | StringCharLen::ByteOffset(offset) => { |
| 280 | builder.append_value(&string[..offset]); |
| 281 | } |
| 282 | StringCharLen::CharCount(char_count) => { |
| 283 | builder.write_str(string)?; |
| 284 | if !fill_chars.is_empty() { |
| 285 | let pad_chars = target_len - char_count; |
| 286 | let pad_bytes = char_byte_offsets[pad_chars]; |
| 287 | builder.write_str(&padding_buf[..pad_bytes])?; |
| 288 | } |
| 289 | builder.append_value(""); |
| 290 | } |
| 291 | }, |
| 292 | None => builder.append_null(), |
| 293 | } |
| 294 | } |
| 295 | |
| 296 | Ok(Arc::new(builder.finish()) as ArrayRef) |
| 297 | } |
| 298 | |
| 299 | fn rpad<T: OffsetSizeTrait>(args: &[ArrayRef]) -> Result<ArrayRef> { |
| 300 | if args.len() <= 1 || args.len() > 3 { |
nothing calls this directly
no test coverage detected
searching dependent graphs…