rust/hg-core/src/utils.rs
changeset 42610 5672bb73f61e
parent 42609 326fdce22fb2
child 42611 2f760da140ee
equal deleted inserted replaced
42609:326fdce22fb2 42610:5672bb73f61e
     1 pub mod files;
     1 pub mod files;
     2 
     2 
       
     3 /// Replaces the `from` slice with the `to` slice inside the `buf` slice.
       
     4 ///
       
     5 /// # Examples
       
     6 ///
       
     7 /// ```
       
     8 /// use crate::hg::utils::replace_slice;
       
     9 /// let mut line = b"I hate writing tests!".to_vec();
       
    10 /// replace_slice(&mut line, b"hate", b"love");
       
    11 /// assert_eq!(
       
    12 ///     line,
       
    13 ///     b"I love writing tests!".to_vec()
       
    14 ///);
       
    15 ///
       
    16 /// ```
     3 pub fn replace_slice<T>(buf: &mut [T], from: &[T], to: &[T])
    17 pub fn replace_slice<T>(buf: &mut [T], from: &[T], to: &[T])
     4 where
    18 where
     5     T: Clone + PartialEq,
    19     T: Clone + PartialEq,
     6 {
    20 {
     7     if buf.len() < from.len() || from.len() != to.len() {
    21     assert_eq!(from.len(), to.len());
       
    22     if buf.len() < from.len() {
     8         return;
    23         return;
     9     }
    24     }
    10     for i in 0..=buf.len() - from.len() {
    25     for i in 0..=buf.len() - from.len() {
    11         if buf[i..].starts_with(from) {
    26         if buf[i..].starts_with(from) {
    12             buf[i..(i + from.len())].clone_from_slice(to);
    27             buf[i..(i + from.len())].clone_from_slice(to);
    13         }
    28         }
    14     }
    29     }
    15 }
    30 }
    16 
    31 
    17 pub trait SliceExt {
    32 pub trait SliceExt {
       
    33     fn trim_end(&self) -> &Self;
       
    34     fn trim_start(&self) -> &Self;
    18     fn trim(&self) -> &Self;
    35     fn trim(&self) -> &Self;
    19     fn trim_end(&self) -> &Self;
       
    20 }
    36 }
    21 
    37 
    22 fn is_not_whitespace(c: &u8) -> bool {
    38 fn is_not_whitespace(c: &u8) -> bool {
    23     !(*c as char).is_whitespace()
    39     !(*c as char).is_whitespace()
    24 }
    40 }
    25 
    41 
    26 impl SliceExt for [u8] {
    42 impl SliceExt for [u8] {
    27     fn trim(&self) -> &[u8] {
       
    28         if let Some(first) = self.iter().position(is_not_whitespace) {
       
    29             if let Some(last) = self.iter().rposition(is_not_whitespace) {
       
    30                 &self[first..last + 1]
       
    31             } else {
       
    32                 unreachable!();
       
    33             }
       
    34         } else {
       
    35             &[]
       
    36         }
       
    37     }
       
    38     fn trim_end(&self) -> &[u8] {
    43     fn trim_end(&self) -> &[u8] {
    39         if let Some(last) = self.iter().rposition(is_not_whitespace) {
    44         if let Some(last) = self.iter().rposition(is_not_whitespace) {
    40             &self[..last + 1]
    45             &self[..last + 1]
    41         } else {
    46         } else {
    42             &[]
    47             &[]
    43         }
    48         }
    44     }
    49     }
       
    50     fn trim_start(&self) -> &[u8] {
       
    51         if let Some(first) = self.iter().position(is_not_whitespace) {
       
    52             &self[first..]
       
    53         } else {
       
    54             &[]
       
    55         }
       
    56     }
       
    57 
       
    58     /// ```
       
    59     /// use hg::utils::SliceExt;
       
    60     /// assert_eq!(
       
    61     ///     b"  to trim  ".trim(),
       
    62     ///     b"to trim"
       
    63     /// );
       
    64     /// assert_eq!(
       
    65     ///     b"to trim  ".trim(),
       
    66     ///     b"to trim"
       
    67     /// );
       
    68     /// assert_eq!(
       
    69     ///     b"  to trim".trim(),
       
    70     ///     b"to trim"
       
    71     /// );
       
    72     /// ```
       
    73     fn trim(&self) -> &[u8] {
       
    74         self.trim_start().trim_end()
       
    75     }
    45 }
    76 }