Skip to main content

lib/
protocol.rs

1use std::io::{BufRead, ErrorKind, Read, Write};
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Serialize, Deserialize, Debug)]
6pub enum Request {
7    Init(String),
8    GetCapabilities,
9    Advance(char),
10    AdvanceStr(String),
11    Reset,
12}
13
14#[derive(Serialize, Deserialize, Debug)]
15pub enum Response {
16    Capabilities(Vec<String>),
17    Expanded(String),
18    Ok,
19}
20
21pub trait WriteNullDelimitedExt {
22    fn write_with_null(&mut self, data: &[u8]) -> std::io::Result<()>;
23    fn write_with_null_flush(&mut self, data: &[u8]) -> std::io::Result<()>;
24}
25
26pub trait ReadUntilNullExt {
27    fn read_until_null(&mut self, buf: &mut String) -> std::io::Result<()>;
28}
29
30impl<S: BufRead> ReadUntilNullExt for S {
31    fn read_until_null(&mut self, buf: &mut String) -> std::io::Result<()> {
32        let mut bytes_buf = Vec::with_capacity(buf.len());
33        self.read_until(0, &mut bytes_buf)?;
34        match str::from_utf8(&bytes_buf) {
35            Ok(str) => buf.push_str(str),
36            Err(_) => return Err(std::io::Error::new(ErrorKind::InvalidInput, "not utf8!")),
37        }
38        Ok(())
39    }
40}
41
42impl<S: Write> WriteNullDelimitedExt for S {
43    fn write_with_null(&mut self, data: &[u8]) -> std::io::Result<()> {
44        self.write(data)?;
45        self.write(&[0])?;
46        Ok(())
47    }
48    fn write_with_null_flush(&mut self, data: &[u8]) -> std::io::Result<()> {
49        self.write_with_null(data)?;
50        self.flush()?;
51        Ok(())
52    }
53}