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 } |