lexical_util/
algorithm.rs

1//! Simple, shared algorithms for slices and iterators.
2
3#[cfg(feature = "write")]
4use core::ptr;
5
6/// Copy bytes from source to destination.
7///
8/// # Safety
9///
10/// Safe as long as `dst` is larger than `src`.
11#[inline]
12#[cfg(feature = "write")]
13pub unsafe fn copy_to_dst<Bytes: AsRef<[u8]>>(dst: &mut [u8], src: Bytes) -> usize {
14    debug_assert!(dst.len() >= src.as_ref().len());
15
16    // SAFETY: safe, if `dst.len() <= src.len()`.
17    let src = src.as_ref();
18    unsafe { ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), src.len()) };
19
20    src.len()
21}
22
23/// Count the number of trailing characters equal to a given value.
24#[inline]
25#[cfg(feature = "write")]
26pub fn rtrim_char_count(slc: &[u8], c: u8) -> usize {
27    slc.iter().rev().take_while(|&&si| si == c).count()
28}
29
30/// Count the number of leading characters equal to a given value.
31#[inline]
32#[cfg(feature = "write")]
33pub fn ltrim_char_count(slc: &[u8], c: u8) -> usize {
34    slc.iter().take_while(|&&si| si == c).count()
35}
36
37/// Trim character from the end (right-side) of a slice.
38#[inline]
39#[cfg(feature = "write")]
40pub fn rtrim_char_slice(slc: &[u8], c: u8) -> (&[u8], usize) {
41    let count = rtrim_char_count(slc, c);
42    let index = slc.len() - count;
43    // Count must be <= slc.len(), and therefore, slc.len() - count must
44    // also be <= slc.len(), since this is derived from an iterator
45    // in the standard library.
46    debug_assert!(count <= slc.len());
47    debug_assert!(index <= slc.len());
48    // SAFETY: safe since `count <= slc.len()` and therefore `index <= slc.len()`.
49    let slc = unsafe { slc.get_unchecked(..index) };
50    (slc, count)
51}