breakwater_parser/
memchr.rs

1use std::sync::Arc;
2
3use crate::{FrameBuffer, Parser};
4
5pub struct MemchrParser<FB: FrameBuffer> {
6    fb: Arc<FB>,
7}
8
9impl<FB: FrameBuffer> MemchrParser<FB> {
10    pub fn new(fb: Arc<FB>) -> Self {
11        Self { fb }
12    }
13}
14
15impl<FB: FrameBuffer> Parser for MemchrParser<FB> {
16    fn parse(&mut self, buffer: &[u8], _response: &mut Vec<u8>) -> usize {
17        let mut last_char_after_newline = 0;
18        for newline in memchr::memchr_iter(b'\n', buffer) {
19            // TODO Use get_unchecked everywhere
20            let line = &buffer[last_char_after_newline..newline.saturating_sub(1)];
21            last_char_after_newline = newline + 1;
22
23            if line.is_empty() {
24                panic!("Line is empty, we probably should handle this");
25            }
26
27            let mut spaces = memchr::memchr_iter(b' ', line);
28            let Some(first_space) = spaces.next() else {
29                continue;
30            };
31
32            match &line[0..first_space] {
33                b"PX" => {
34                    let Some(second_space) = spaces.next() else {
35                        continue;
36                    };
37                    let Some(third_space) = spaces.next() else {
38                        continue;
39                    };
40                    let Some(fourth_space) = spaces.next() else {
41                        continue;
42                    };
43                    let x: u16 = std::str::from_utf8(&line[first_space + 1..second_space])
44                        .expect("Not utf-8")
45                        .parse()
46                        .expect("x was not a number");
47                    let y: u16 = std::str::from_utf8(&line[second_space + 1..third_space])
48                        .expect("Not utf-8")
49                        .parse()
50                        .expect("y was not a number");
51                    let rgba: u32 = std::str::from_utf8(&line[third_space + 1..fourth_space])
52                        .expect("Not utf-8")
53                        .parse()
54                        .expect("rgba was not a number");
55
56                    self.fb.set(x as usize, y as usize, rgba);
57                }
58                _ => {
59                    continue;
60                }
61            }
62        }
63
64        last_char_after_newline.saturating_sub(1)
65    }
66
67    fn parser_lookahead(&self) -> usize {
68        0
69    }
70}