#[cfg(target_arch = "wasm32")]
compile_error!("This module should not be included when compiling to wasm");
use std::io::{BufRead, BufReader, Read, Write};
use serde::{Serialize, de::DeserializeOwned};
use serde_json::{self, error::Category};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct Disconnected;
pub fn read_forever<R: Read, T: DeserializeOwned, F: FnMut(T) -> Result<(), Disconnected>>(
reader: R,
unable_to_read_bytes: &'static str,
failed_to_read_result: &'static str,
mut handler: F,
) {
let mut reader = BufReader::new(reader);
loop {
let mut buffer = String::new();
let read_bytes = reader.read_line(&mut buffer).expect(unable_to_read_bytes);
if read_bytes == 0 {
break;
}
let result = serde_json::from_str(&buffer)
.map_err(|err| match err.classify() {
Category::Io | Category::Syntax | Category::Data => panic!(failed_to_read_result),
Category::Eof => Disconnected,
})
.and_then(|result| handler(result));
if result.is_err() {
break;
}
}
}
pub fn send<W: Write, T: Serialize>(mut writer: W, message: &T, unable_to_write_newline: &str) -> Result<(), Disconnected> {
serde_json::to_writer(&mut writer, message)
.map_err(|err| match err.classify() {
Category::Io | Category::Eof => Disconnected,
Category::Syntax | Category::Data => unreachable!("bug: got an input error when writing output"),
})
.map(|_| writeln!(writer).expect(unable_to_write_newline))
}