1 //! Defines messages for cross-process message passing based on `ndjson` wire protocol
5 io::{self, BufRead, Write},
8 use serde::{de::DeserializeOwned, Deserialize, Serialize};
11 rpc::{ListMacrosResult, ListMacrosTask},
12 ExpansionResult, ExpansionTask,
15 #[derive(Debug, Serialize, Deserialize, Clone)]
17 ListMacro(ListMacrosTask),
18 ExpansionMacro(ExpansionTask),
21 #[derive(Debug, Serialize, Deserialize, Clone)]
24 ListMacro(ListMacrosResult),
25 ExpansionMacro(ExpansionResult),
28 macro_rules! impl_try_from_response {
29 ($ty:ty, $tag:ident) => {
30 impl TryFrom<Response> for $ty {
31 type Error = &'static str;
32 fn try_from(value: Response) -> Result<Self, Self::Error> {
34 Response::$tag(res) => Ok(res),
35 _ => Err(concat!("Failed to convert response to ", stringify!($tag))),
42 impl_try_from_response!(ListMacrosResult, ListMacro);
43 impl_try_from_response!(ExpansionResult, ExpansionMacro);
45 #[derive(Debug, Serialize, Deserialize, Clone)]
46 pub struct ResponseError {
51 #[derive(Debug, Serialize, Deserialize, Clone)]
57 pub trait Message: Serialize + DeserializeOwned {
58 fn read(inp: &mut impl BufRead) -> io::Result<Option<Self>> {
59 Ok(match read_json(inp)? {
62 let mut deserializer = serde_json::Deserializer::from_str(&text);
63 // Note that some proc-macro generate very deep syntax tree
64 // We have to disable the current limit of serde here
65 deserializer.disable_recursion_limit();
66 Some(Self::deserialize(&mut deserializer)?)
70 fn write(self, out: &mut impl Write) -> io::Result<()> {
71 let text = serde_json::to_string(&self)?;
72 write_json(out, &text)
76 impl Message for Request {}
77 impl Message for Response {}
79 fn read_json(inp: &mut impl BufRead) -> io::Result<Option<String>> {
80 let mut buf = String::new();
81 inp.read_line(&mut buf)?;
82 buf.pop(); // Remove trailing '\n'
89 fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> {
90 log::debug!("> {}", msg);
91 out.write_all(msg.as_bytes())?;
92 out.write_all(b"\n")?;