1use crate::stream::PushBackable;
2use futures::{Stream, StreamExt};
3
4#[doc(hidden)]
5#[macro_export]
6macro_rules! try_parse {
7 ($input:expr) => {
8 match $input.await? {
9 ParseResult::Ok(b) => b,
10 ParseResult::Input(e) => return Some(ParseResult::Input(e)),
11 ParseResult::Parsing(e) => return Some(ParseResult::Parsing(e)),
12 }
13 };
14}
15
16#[doc(hidden)]
17#[macro_export]
18macro_rules! try_result {
19 ($input:expr) => {
20 match $input.await? {
21 Ok(b) => b,
22 Err(e) => return Some(ParseResult::Input(e)),
23 }
24 };
25}
26
27pub(crate) async fn skip_whitespaces<S, E>(input: &mut S) -> Option<Result<(), E>>
28where
29 S: Stream<Item = Result<u8, E>> + Unpin + PushBackable<Item = u8>,
30{
31 loop {
32 let b = match input.next().await? {
33 Ok(b) => b,
34 Err(e) => return Some(Err(e)),
35 };
36 if b != b' ' {
37 input.push_back(b);
38 break;
39 }
40 }
41 Some(Ok(()))
42}
43
44#[cfg(itest)]
45mod test {
46 use super::{skip_whitespaces, stream, StreamExt};
47
48 #[cfg(not(feature = "parse-checksum"))]
49 use crate::stream::pushback::PushBack;
50 #[cfg(feature = "parse-checksum")]
51 use crate::stream::xorsum_pushback::XorSumPushBack;
52
53 #[test]
54 fn skips_white_spaces_and_pushes_back_the_first_non_space_byte() {
55 let mut data = PushBack::new(stream::iter(
56 b" d"
57 .iter()
58 .copied()
59 .map(Result::<_, core::convert::Infallible>::Ok),
60 ));
61 futures_executor::block_on(async move {
62 skip_whitespaces(&mut data).await;
63 assert_eq!(Some(Ok(b'd')), data.next().await);
64 });
65 }
66}