comparison rust/hg-core/src/utils.rs @ 42610:5672bb73f61e

rust-utils: add docstrings and doctests for utils.rs Differential Revision: https://phab.mercurial-scm.org/D6635
author Rapha?l Gom?s <rgomes@octobus.net>
date Wed, 10 Jul 2019 17:41:07 +0200
parents 326fdce22fb2
children 2f760da140ee
comparison
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 }