comparison rust/hg-core/src/utils.rs @ 47949:696abab107b4

rust: Generalize the `trim_end_newlines` utility of byte strings ? into `trim_end_matches` that takes a callack. Also add `trim_start_matches`. Differential Revision: https://phab.mercurial-scm.org/D11388
author Simon Sapin <simon.sapin@octobus.net>
date Fri, 03 Sep 2021 16:37:20 +0200
parents 91ab5190a3de
children 4d2a5ca060e3
comparison
equal deleted inserted replaced
47948:83f0e93ec34b 47949:696abab107b4
65 } 65 }
66 } 66 }
67 } 67 }
68 68
69 pub trait SliceExt { 69 pub trait SliceExt {
70 fn trim_end_newlines(&self) -> &Self;
71 fn trim_end(&self) -> &Self; 70 fn trim_end(&self) -> &Self;
72 fn trim_start(&self) -> &Self; 71 fn trim_start(&self) -> &Self;
72 fn trim_end_matches(&self, f: impl FnMut(u8) -> bool) -> &Self;
73 fn trim_start_matches(&self, f: impl FnMut(u8) -> bool) -> &Self;
73 fn trim(&self) -> &Self; 74 fn trim(&self) -> &Self;
74 fn drop_prefix(&self, needle: &Self) -> Option<&Self>; 75 fn drop_prefix(&self, needle: &Self) -> Option<&Self>;
75 fn split_2(&self, separator: u8) -> Option<(&[u8], &[u8])>; 76 fn split_2(&self, separator: u8) -> Option<(&[u8], &[u8])>;
76 } 77 }
77 78
78 #[allow(clippy::trivially_copy_pass_by_ref)]
79 fn is_not_whitespace(c: &u8) -> bool {
80 !(*c as char).is_whitespace()
81 }
82
83 impl SliceExt for [u8] { 79 impl SliceExt for [u8] {
84 fn trim_end_newlines(&self) -> &[u8] { 80 fn trim_end(&self) -> &[u8] {
85 if let Some(last) = self.iter().rposition(|&byte| byte != b'\n') { 81 self.trim_end_matches(|byte| byte.is_ascii_whitespace())
82 }
83
84 fn trim_start(&self) -> &[u8] {
85 self.trim_start_matches(|byte| byte.is_ascii_whitespace())
86 }
87
88 fn trim_end_matches(&self, mut f: impl FnMut(u8) -> bool) -> &Self {
89 if let Some(last) = self.iter().rposition(|&byte| !f(byte)) {
86 &self[..=last] 90 &self[..=last]
87 } else { 91 } else {
88 &[] 92 &[]
89 } 93 }
90 } 94 }
91 fn trim_end(&self) -> &[u8] { 95
92 if let Some(last) = self.iter().rposition(is_not_whitespace) { 96 fn trim_start_matches(&self, mut f: impl FnMut(u8) -> bool) -> &Self {
93 &self[..=last] 97 if let Some(first) = self.iter().position(|&byte| !f(byte)) {
94 } else {
95 &[]
96 }
97 }
98 fn trim_start(&self) -> &[u8] {
99 if let Some(first) = self.iter().position(is_not_whitespace) {
100 &self[first..] 98 &self[first..]
101 } else { 99 } else {
102 &[] 100 &[]
103 } 101 }
104 } 102 }