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}