Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/proc-macro-api/src/legacy_protocol/json.rs')
-rw-r--r--crates/proc-macro-api/src/legacy_protocol/json.rs74
1 files changed, 48 insertions, 26 deletions
diff --git a/crates/proc-macro-api/src/legacy_protocol/json.rs b/crates/proc-macro-api/src/legacy_protocol/json.rs
index c8f774031b..1359c05684 100644
--- a/crates/proc-macro-api/src/legacy_protocol/json.rs
+++ b/crates/proc-macro-api/src/legacy_protocol/json.rs
@@ -1,36 +1,58 @@
//! Protocol functions for json.
use std::io::{self, BufRead, Write};
-/// Reads a JSON message from the input stream.
-pub fn read_json<'a>(
- inp: &mut impl BufRead,
- buf: &'a mut String,
-) -> io::Result<Option<&'a String>> {
- loop {
- buf.clear();
-
- inp.read_line(buf)?;
- buf.pop(); // Remove trailing '\n'
-
- if buf.is_empty() {
- return Ok(None);
- }
+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'
- // 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;
+ 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));
}
+ }
- 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()
}
}
-/// Writes a JSON message to the output stream.
-pub fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> {
- tracing::debug!("> {}", msg);
- out.write_all(msg.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)?)
+ }
}