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