blob: 1359c0568402aaaabe684bd0be8cb3ea738a4ee5 [file] [log] [blame]
//! Protocol functions for json.
use std::io::{self, BufRead, Write};
use serde::{Serialize, de::DeserializeOwned};
use crate::{codec::Codec, framing::Framing};
pub struct JsonProtocol;
impl Framing for JsonProtocol {
type Buf = String;
fn read<'a, R: BufRead>(
inp: &mut R,
buf: &'a mut String,
) -> io::Result<Option<&'a mut String>> {
loop {
buf.clear();
inp.read_line(buf)?;
buf.pop(); // Remove trailing '\n'
if buf.is_empty() {
return Ok(None);
}
// Some ill behaved macro try to use stdout for debugging
// We ignore it here
if !buf.starts_with('{') {
tracing::error!("proc-macro tried to print : {}", buf);
continue;
}
return Ok(Some(buf));
}
}
fn write<W: Write>(out: &mut W, buf: &String) -> io::Result<()> {
tracing::debug!("> {}", buf);
out.write_all(buf.as_bytes())?;
out.write_all(b"\n")?;
out.flush()
}
}
impl Codec for JsonProtocol {
fn encode<T: Serialize>(msg: &T) -> io::Result<String> {
Ok(serde_json::to_string(msg)?)
}
fn decode<T: DeserializeOwned>(buf: &mut String) -> io::Result<T> {
let mut deserializer = serde_json::Deserializer::from_str(buf);
// Note that some proc-macro generate very deep syntax tree
// We have to disable the current limit of serde here
deserializer.disable_recursion_limit();
Ok(T::deserialize(&mut deserializer)?)
}
}