watermelon-proto 0.1.8

#[no_std] NATS Core Sans-IO protocol implementation
Documentation
use core::{iter, mem};

use bytes::{Buf, Bytes};

pub(crate) fn split_spaces(mut bytes: Bytes) -> impl Iterator<Item = Bytes> {
    iter::from_fn(move || {
        if bytes.is_empty() {
            return None;
        }

        let Some(i) = memchr::memchr2(b' ', b'\t', &bytes) else {
            return Some(mem::take(&mut bytes));
        };

        let chunk = bytes.split_to(i);

        let spaces = bytes
            .iter()
            .take_while(|b| matches!(b, b' ' | b'\t'))
            .count();
        debug_assert!(spaces > 0);
        bytes.advance(spaces);
        Some(chunk)
    })
}

#[cfg(test)]
mod tests {
    use bytes::Bytes;

    use super::split_spaces;

    #[test]
    fn combinations() {
        let tests: &[(&str, &[&str])] = &[
            ("", &[]),
            ("0123456789abcdef", &["0123456789abcdef"]),
            ("012345 6789abcdef", &["012345", "6789abcdef"]),
            ("012345\t6789abcdef", &["012345", "6789abcdef"]),
            ("012345  6789abcdef", &["012345", "6789abcdef"]),
            ("012345        6789abcdef", &["012345", "6789abcdef"]),
            ("012345\t\t6789abcdef", &["012345", "6789abcdef"]),
            ("012345\t\t\t\t6789abcdef", &["012345", "6789abcdef"]),
            ("012345 \t \t\t\t 6789abcdef", &["012345", "6789abcdef"]),
            ("012345 678 9abcdef", &["012345", "678", "9abcdef"]),
            ("012345 678\t9abcdef", &["012345", "678", "9abcdef"]),
            ("012345\t678 9abcdef", &["012345", "678", "9abcdef"]),
            ("012345\t678\t9abcdef", &["012345", "678", "9abcdef"]),
            ("012345\t678\t 9abcdef", &["012345", "678", "9abcdef"]),
            ("012345 \t678\t 9abcdef", &["012345", "678", "9abcdef"]),
        ];

        for (input, output) in tests {
            let spaces = split_spaces(Bytes::from_static(input.as_bytes())).collect::<Vec<Bytes>>();
            assert_eq!(spaces, output.to_vec());
        }
    }
}