async_gcode/
utils.rs

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}