Skip to content

Commit f7448a7

Browse files
dbrgnworkingjubilee
andcommitted
core: Implement trim functions on byte slices
Co-authored-by: Jubilee Young <workingjubilee@gmail.com>
1 parent 88fb06a commit f7448a7

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

library/core/src/slice/ascii.rs

+78
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,84 @@ impl [u8] {
8080
pub fn escape_ascii(&self) -> EscapeAscii<'_> {
8181
EscapeAscii { inner: self.iter().flat_map(EscapeByte) }
8282
}
83+
84+
/// Returns a byte slice with leading ASCII whitespace bytes removed.
85+
///
86+
/// 'Whitespace' refers to the definition used by
87+
/// `u8::is_ascii_whitespace`.
88+
///
89+
/// # Examples
90+
///
91+
/// ```
92+
/// #![feature(byte_slice_trim_ascii)]
93+
///
94+
/// assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
95+
/// assert_eq!(b" ".trim_ascii_start(), b"");
96+
/// assert_eq!(b"".trim_ascii_start(), b"");
97+
/// ```
98+
#[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
99+
pub const fn trim_ascii_start(&self) -> &[u8] {
100+
let mut bytes = self;
101+
// Note: A pattern matching based approach (instead of indexing) allows
102+
// making the function const.
103+
while let [first, rest @ ..] = bytes {
104+
if first.is_ascii_whitespace() {
105+
bytes = rest;
106+
} else {
107+
break;
108+
}
109+
}
110+
bytes
111+
}
112+
113+
/// Returns a byte slice with trailing ASCII whitespace bytes removed.
114+
///
115+
/// 'Whitespace' refers to the definition used by
116+
/// `u8::is_ascii_whitespace`.
117+
///
118+
/// # Examples
119+
///
120+
/// ```
121+
/// #![feature(byte_slice_trim_ascii)]
122+
///
123+
/// assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
124+
/// assert_eq!(b" ".trim_ascii_end(), b"");
125+
/// assert_eq!(b"".trim_ascii_end(), b"");
126+
/// ```
127+
#[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
128+
pub const fn trim_ascii_end(&self) -> &[u8] {
129+
let mut bytes = self;
130+
// Note: A pattern matching based approach (instead of indexing) allows
131+
// making the function const.
132+
while let [rest @ .., last] = bytes {
133+
if last.is_ascii_whitespace() {
134+
bytes = rest;
135+
} else {
136+
break;
137+
}
138+
}
139+
bytes
140+
}
141+
142+
/// Returns a byte slice with leading and trailing ASCII whitespace bytes
143+
/// removed.
144+
///
145+
/// 'Whitespace' refers to the definition used by
146+
/// `u8::is_ascii_whitespace`.
147+
///
148+
/// # Examples
149+
///
150+
/// ```
151+
/// #![feature(byte_slice_trim_ascii)]
152+
///
153+
/// assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
154+
/// assert_eq!(b" ".trim_ascii(), b"");
155+
/// assert_eq!(b"".trim_ascii(), b"");
156+
/// ```
157+
#[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
158+
pub const fn trim_ascii(&self) -> &[u8] {
159+
self.trim_ascii_start().trim_ascii_end()
160+
}
83161
}
84162

85163
impl_fn_for_zst! {

0 commit comments

Comments
 (0)