]> git.lizzy.rs Git - rust.git/blobdiff - crates/proc_macro_api/src/msg.rs
clippy::redudant_borrow
[rust.git] / crates / proc_macro_api / src / msg.rs
index 4cd572101614550c606e21bd36d5b68ee9e604dc..899895578682cd4d2e92a686bc768391fd2f8748 100644 (file)
@@ -55,11 +55,11 @@ pub enum ErrorCode {
 }
 
 pub trait Message: Serialize + DeserializeOwned {
-    fn read(inp: &mut impl BufRead) -> io::Result<Option<Self>> {
-        Ok(match read_json(inp)? {
+    fn read(inp: &mut impl BufRead, buf: &mut String) -> io::Result<Option<Self>> {
+        Ok(match read_json(inp, buf)? {
             None => None,
             Some(text) => {
-                let mut deserializer = serde_json::Deserializer::from_str(&text);
+                let mut deserializer = serde_json::Deserializer::from_str(text);
                 // Note that some proc-macro generate very deep syntax tree
                 // We have to disable the current limit of serde here
                 deserializer.disable_recursion_limit();
@@ -76,14 +76,29 @@ fn write(self, out: &mut impl Write) -> io::Result<()> {
 impl Message for Request {}
 impl Message for Response {}
 
-fn read_json(inp: &mut impl BufRead) -> io::Result<Option<String>> {
-    let mut buf = String::new();
-    inp.read_line(&mut buf)?;
-    buf.pop(); // Remove traling '\n'
-    Ok(match buf.len() {
-        0 => None,
-        _ => Some(buf),
-    })
+fn read_json<'a>(
+    inp: &mut impl BufRead,
+    mut buf: &'a mut String,
+) -> io::Result<Option<&'a String>> {
+    loop {
+        buf.clear();
+
+        inp.read_line(&mut 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('{') {
+            log::error!("proc-macro tried to print : {}", buf);
+            continue;
+        }
+
+        return Ok(Some(buf));
+    }
 }
 
 fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> {