Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--Cargo.lock15
-rw-r--r--Cargo.toml1
-rw-r--r--crates/proc-macro-api/Cargo.toml1
-rw-r--r--crates/proc-macro-api/src/codec.rs12
-rw-r--r--crates/proc-macro-api/src/framing.rs14
-rw-r--r--crates/proc-macro-api/src/legacy_protocol.rs19
-rw-r--r--crates/proc-macro-api/src/legacy_protocol/json.rs74
-rw-r--r--crates/proc-macro-api/src/legacy_protocol/msg.rs32
-rw-r--r--crates/proc-macro-api/src/legacy_protocol/postcard.rs40
-rw-r--r--crates/proc-macro-api/src/lib.rs11
-rw-r--r--crates/proc-macro-api/src/process.rs129
-rw-r--r--crates/proc-macro-srv-cli/Cargo.toml5
-rw-r--r--crates/proc-macro-srv-cli/src/main.rs5
-rw-r--r--crates/proc-macro-srv-cli/src/main_loop.rs18
14 files changed, 262 insertions, 114 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4de8d09dca..d78c0f765d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -561,6 +561,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
+name = "embedded-io"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
+
+[[package]]
+name = "embedded-io"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
+
+[[package]]
name = "ena"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1785,6 +1797,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
dependencies = [
"cobs",
+ "embedded-io 0.4.0",
+ "embedded-io 0.6.1",
"heapless",
"serde",
]
@@ -1820,6 +1834,7 @@ dependencies = [
"indexmap",
"intern",
"paths",
+ "postcard",
"proc-macro-srv",
"rustc-hash 2.1.1",
"serde",
diff --git a/Cargo.toml b/Cargo.toml
index 8ff7e0e8a2..946e54b40b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -127,6 +127,7 @@ object = { version = "0.36.7", default-features = false, features = [
"macho",
"pe",
] }
+postcard = {version = "1.1.3", features = ["alloc"]}
process-wrap = { version = "8.2.1", features = ["std"] }
pulldown-cmark-to-cmark = "10.0.4"
pulldown-cmark = { version = "0.9.6", default-features = false }
diff --git a/crates/proc-macro-api/Cargo.toml b/crates/proc-macro-api/Cargo.toml
index 63745b9f74..4077e11b71 100644
--- a/crates/proc-macro-api/Cargo.toml
+++ b/crates/proc-macro-api/Cargo.toml
@@ -29,6 +29,7 @@ proc-macro-srv = {workspace = true, optional = true}
span = { path = "../span", version = "0.0.0", default-features = false}
intern.workspace = true
+postcard.workspace = true
[features]
sysroot-abi = ["proc-macro-srv", "proc-macro-srv/sysroot-abi"]
diff --git a/crates/proc-macro-api/src/codec.rs b/crates/proc-macro-api/src/codec.rs
new file mode 100644
index 0000000000..baccaa6be4
--- /dev/null
+++ b/crates/proc-macro-api/src/codec.rs
@@ -0,0 +1,12 @@
+//! Protocol codec
+
+use std::io;
+
+use serde::de::DeserializeOwned;
+
+use crate::framing::Framing;
+
+pub trait Codec: Framing {
+ fn encode<T: serde::Serialize>(msg: &T) -> io::Result<Self::Buf>;
+ fn decode<T: DeserializeOwned>(buf: &mut Self::Buf) -> io::Result<T>;
+}
diff --git a/crates/proc-macro-api/src/framing.rs b/crates/proc-macro-api/src/framing.rs
new file mode 100644
index 0000000000..a1e6fc05ca
--- /dev/null
+++ b/crates/proc-macro-api/src/framing.rs
@@ -0,0 +1,14 @@
+//! Protocol framing
+
+use std::io::{self, BufRead, Write};
+
+pub trait Framing {
+ type Buf: Default;
+
+ fn read<'a, R: BufRead>(
+ inp: &mut R,
+ buf: &'a mut Self::Buf,
+ ) -> io::Result<Option<&'a mut Self::Buf>>;
+
+ fn write<W: Write>(out: &mut W, buf: &Self::Buf) -> io::Result<()>;
+}
diff --git a/crates/proc-macro-api/src/legacy_protocol.rs b/crates/proc-macro-api/src/legacy_protocol.rs
index 0a72052cc5..c2b132ddcc 100644
--- a/crates/proc-macro-api/src/legacy_protocol.rs
+++ b/crates/proc-macro-api/src/legacy_protocol.rs
@@ -2,6 +2,7 @@
pub mod json;
pub mod msg;
+pub mod postcard;
use std::{
io::{BufRead, Write},
@@ -13,13 +14,15 @@ use span::Span;
use crate::{
ProcMacro, ProcMacroKind, ServerError,
+ codec::Codec,
legacy_protocol::{
- json::{read_json, write_json},
+ json::JsonProtocol,
msg::{
ExpandMacro, ExpandMacroData, ExpnGlobals, FlatTree, Message, Request, Response,
ServerConfig, SpanDataIndexMap, deserialize_span_data_index_map,
flat::serialize_span_data_index_map,
},
+ postcard::PostcardProtocol,
},
process::ProcMacroServerProcess,
version,
@@ -151,21 +154,25 @@ fn send_task(srv: &ProcMacroServerProcess, req: Request) -> Result<Response, Ser
return Err(server_error.clone());
}
- srv.send_task(send_request, req)
+ if srv.use_postcard() {
+ srv.send_task(send_request::<PostcardProtocol>, req)
+ } else {
+ srv.send_task(send_request::<JsonProtocol>, req)
+ }
}
/// Sends a request to the server and reads the response.
-fn send_request(
+fn send_request<P: Codec>(
mut writer: &mut dyn Write,
mut reader: &mut dyn BufRead,
req: Request,
- buf: &mut String,
+ buf: &mut P::Buf,
) -> Result<Option<Response>, ServerError> {
- req.write(write_json, &mut writer).map_err(|err| ServerError {
+ req.write::<_, P>(&mut writer).map_err(|err| ServerError {
message: "failed to write request".into(),
io: Some(Arc::new(err)),
})?;
- let res = Response::read(read_json, &mut reader, buf).map_err(|err| ServerError {
+ let res = Response::read::<_, P>(&mut reader, buf).map_err(|err| ServerError {
message: "failed to read response".into(),
io: Some(Arc::new(err)),
})?;
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)?)
+ }
}
diff --git a/crates/proc-macro-api/src/legacy_protocol/msg.rs b/crates/proc-macro-api/src/legacy_protocol/msg.rs
index 487f50b145..1c77863aac 100644
--- a/crates/proc-macro-api/src/legacy_protocol/msg.rs
+++ b/crates/proc-macro-api/src/legacy_protocol/msg.rs
@@ -8,7 +8,7 @@ use paths::Utf8PathBuf;
use serde::de::DeserializeOwned;
use serde_derive::{Deserialize, Serialize};
-use crate::ProcMacroKind;
+use crate::{ProcMacroKind, codec::Codec};
/// Represents requests sent from the client to the proc-macro-srv.
#[derive(Debug, Serialize, Deserialize)]
@@ -149,39 +149,21 @@ impl ExpnGlobals {
}
pub trait Message: serde::Serialize + DeserializeOwned {
- fn read<R: BufRead>(
- from_proto: ProtocolRead<R>,
- inp: &mut R,
- buf: &mut String,
- ) -> io::Result<Option<Self>> {
- Ok(match from_proto(inp, buf)? {
+ fn read<R: BufRead, C: Codec>(inp: &mut R, buf: &mut C::Buf) -> io::Result<Option<Self>> {
+ Ok(match C::read(inp, buf)? {
None => None,
- Some(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();
- Some(Self::deserialize(&mut deserializer)?)
- }
+ Some(buf) => C::decode(buf)?,
})
}
- fn write<W: Write>(self, to_proto: ProtocolWrite<W>, out: &mut W) -> io::Result<()> {
- let text = serde_json::to_string(&self)?;
- to_proto(out, &text)
+ fn write<W: Write, C: Codec>(self, out: &mut W) -> io::Result<()> {
+ let value = C::encode(&self)?;
+ C::write(out, &value)
}
}
impl Message for Request {}
impl Message for Response {}
-/// Type alias for a function that reads protocol messages from a buffered input stream.
-#[allow(type_alias_bounds)]
-type ProtocolRead<R: BufRead> =
- for<'i, 'buf> fn(inp: &'i mut R, buf: &'buf mut String) -> io::Result<Option<&'buf String>>;
-/// Type alias for a function that writes protocol messages to an output stream.
-#[allow(type_alias_bounds)]
-type ProtocolWrite<W: Write> = for<'o, 'msg> fn(out: &'o mut W, msg: &'msg str) -> io::Result<()>;
-
#[cfg(test)]
mod tests {
use intern::{Symbol, sym};
diff --git a/crates/proc-macro-api/src/legacy_protocol/postcard.rs b/crates/proc-macro-api/src/legacy_protocol/postcard.rs
new file mode 100644
index 0000000000..c28a9bfe3a
--- /dev/null
+++ b/crates/proc-macro-api/src/legacy_protocol/postcard.rs
@@ -0,0 +1,40 @@
+//! Postcard encode and decode implementations.
+
+use std::io::{self, BufRead, Write};
+
+use serde::{Serialize, de::DeserializeOwned};
+
+use crate::{codec::Codec, framing::Framing};
+
+pub struct PostcardProtocol;
+
+impl Framing for PostcardProtocol {
+ type Buf = Vec<u8>;
+
+ fn read<'a, R: BufRead>(
+ inp: &mut R,
+ buf: &'a mut Vec<u8>,
+ ) -> io::Result<Option<&'a mut Vec<u8>>> {
+ buf.clear();
+ let n = inp.read_until(0, buf)?;
+ if n == 0 {
+ return Ok(None);
+ }
+ Ok(Some(buf))
+ }
+
+ fn write<W: Write>(out: &mut W, buf: &Vec<u8>) -> io::Result<()> {
+ out.write_all(buf)?;
+ out.flush()
+ }
+}
+
+impl Codec for PostcardProtocol {
+ fn encode<T: Serialize>(msg: &T) -> io::Result<Vec<u8>> {
+ postcard::to_allocvec_cobs(msg).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
+ }
+
+ fn decode<T: DeserializeOwned>(buf: &mut Self::Buf) -> io::Result<T> {
+ postcard::from_bytes_cobs(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
+ }
+}
diff --git a/crates/proc-macro-api/src/lib.rs b/crates/proc-macro-api/src/lib.rs
index 870d81f976..a725b94f04 100644
--- a/crates/proc-macro-api/src/lib.rs
+++ b/crates/proc-macro-api/src/lib.rs
@@ -12,6 +12,8 @@
)]
#![allow(internal_features)]
+mod codec;
+mod framing;
pub mod legacy_protocol;
mod process;
@@ -19,7 +21,8 @@ use paths::{AbsPath, AbsPathBuf};
use span::{ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, Span};
use std::{fmt, io, sync::Arc, time::SystemTime};
-use crate::process::ProcMacroServerProcess;
+pub use crate::codec::Codec;
+use crate::{legacy_protocol::SpanMode, process::ProcMacroServerProcess};
/// The versions of the server protocol
pub mod version {
@@ -123,7 +126,11 @@ impl ProcMacroClient {
Item = (impl AsRef<std::ffi::OsStr>, &'a Option<impl 'a + AsRef<std::ffi::OsStr>>),
> + Clone,
) -> io::Result<ProcMacroClient> {
- let process = ProcMacroServerProcess::run(process_path, env)?;
+ let process = ProcMacroServerProcess::run(
+ process_path,
+ env,
+ process::Protocol::Postcard { mode: SpanMode::Id },
+ )?;
Ok(ProcMacroClient { process: Arc::new(process), path: process_path.to_owned() })
}
diff --git a/crates/proc-macro-api/src/process.rs b/crates/proc-macro-api/src/process.rs
index fe274a027a..1365245f98 100644
--- a/crates/proc-macro-api/src/process.rs
+++ b/crates/proc-macro-api/src/process.rs
@@ -28,9 +28,10 @@ pub(crate) struct ProcMacroServerProcess {
exited: OnceLock<AssertUnwindSafe<ServerError>>,
}
-#[derive(Debug)]
-enum Protocol {
+#[derive(Debug, Clone)]
+pub(crate) enum Protocol {
LegacyJson { mode: SpanMode },
+ Postcard { mode: SpanMode },
}
/// Maintains the state of the proc-macro server process.
@@ -48,50 +49,82 @@ impl ProcMacroServerProcess {
env: impl IntoIterator<
Item = (impl AsRef<std::ffi::OsStr>, &'a Option<impl 'a + AsRef<std::ffi::OsStr>>),
> + Clone,
+ protocol: Protocol,
) -> io::Result<ProcMacroServerProcess> {
- let create_srv = || {
- let mut process = Process::run(process_path, env.clone())?;
+ let mut srv = {
+ let mut process = match Process::run(process_path, env.clone(), &protocol) {
+ Ok(process) => process,
+ Err(e) => {
+ // fallback
+ if matches!(protocol, Protocol::Postcard { .. }) {
+ // retry with json
+ return Self::run(
+ process_path,
+ env,
+ Protocol::LegacyJson { mode: SpanMode::Id },
+ );
+ }
+ return Err(e);
+ }
+ };
let (stdin, stdout) = process.stdio().expect("couldn't access child stdio");
- io::Result::Ok(ProcMacroServerProcess {
+ ProcMacroServerProcess {
state: Mutex::new(ProcessSrvState { process, stdin, stdout }),
version: 0,
- protocol: Protocol::LegacyJson { mode: SpanMode::Id },
+ protocol: protocol.clone(),
exited: OnceLock::new(),
- })
+ }
};
- let mut srv = create_srv()?;
tracing::info!("sending proc-macro server version check");
- match srv.version_check() {
- Ok(v) if v > version::CURRENT_API_VERSION => {
- #[allow(clippy::disallowed_methods)]
- let process_version = Command::new(process_path)
- .arg("--version")
- .output()
- .map(|output| String::from_utf8_lossy(&output.stdout).trim().to_owned())
- .unwrap_or_else(|_| "unknown version".to_owned());
- Err(io::Error::other(format!(
- "Your installed proc-macro server is too new for your rust-analyzer. API version: {}, server version: {process_version}. \
- This will prevent proc-macro expansion from working. Please consider updating your rust-analyzer to ensure compatibility with your current toolchain.",
- version::CURRENT_API_VERSION
- )))
- }
- Ok(v) => {
- tracing::info!("Proc-macro server version: {v}");
- srv.version = v;
- if srv.version >= version::RUST_ANALYZER_SPAN_SUPPORT
- && let Ok(mode) = srv.enable_rust_analyzer_spans()
- {
- srv.protocol = Protocol::LegacyJson { mode };
- }
- tracing::info!("Proc-macro server protocol: {:?}", srv.protocol);
- Ok(srv)
- }
+ let version = match srv.version_check() {
+ Ok(v) => v,
Err(e) => {
+ if matches!(protocol, Protocol::Postcard { .. }) {
+ // retry with json
+ return Self::run(
+ process_path,
+ env,
+ Protocol::LegacyJson { mode: SpanMode::Id },
+ );
+ }
+
tracing::info!(%e, "proc-macro version check failed");
- Err(io::Error::other(format!("proc-macro server version check failed: {e}")))
+ return Err(io::Error::other(format!(
+ "proc-macro server version check failed: {e}"
+ )));
}
+ };
+
+ if version > version::CURRENT_API_VERSION {
+ #[allow(clippy::disallowed_methods)]
+ let process_version = Command::new(process_path)
+ .arg("--version")
+ .output()
+ .map(|out| String::from_utf8_lossy(&out.stdout).trim().to_owned())
+ .unwrap_or_else(|_| "unknown version".to_owned());
+
+ return Err(io::Error::other(format!(
+ "Your installed proc-macro server is too new for your rust-analyzer. API version: {}, server version: {process_version}. \
+ This will prevent proc-macro expansion from working. Please consider updating your rust-analyzer to ensure compatibility with your current toolchain.",
+ version::CURRENT_API_VERSION
+ )));
}
+
+ tracing::info!("proc-macro server version: {version}");
+
+ srv.version = version;
+
+ if version >= version::RUST_ANALYZER_SPAN_SUPPORT
+ && let Ok(new_mode) = srv.enable_rust_analyzer_spans()
+ {
+ match &mut srv.protocol {
+ Protocol::Postcard { mode } | Protocol::LegacyJson { mode } => *mode = new_mode,
+ };
+ }
+
+ tracing::info!("proc-macro server protocol: {:?}", srv.protocol);
+ Ok(srv)
}
/// Returns the server error if the process has exited.
@@ -99,6 +132,10 @@ impl ProcMacroServerProcess {
self.exited.get().map(|it| &it.0)
}
+ pub(crate) fn use_postcard(&self) -> bool {
+ matches!(self.protocol, Protocol::Postcard { .. })
+ }
+
/// Retrieves the API version of the proc-macro server.
pub(crate) fn version(&self) -> u32 {
self.version
@@ -108,6 +145,7 @@ impl ProcMacroServerProcess {
pub(crate) fn rust_analyzer_spans(&self) -> bool {
match self.protocol {
Protocol::LegacyJson { mode } => mode == SpanMode::RustAnalyzer,
+ Protocol::Postcard { mode } => mode == SpanMode::RustAnalyzer,
}
}
@@ -115,6 +153,7 @@ impl ProcMacroServerProcess {
fn version_check(&self) -> Result<u32, ServerError> {
match self.protocol {
Protocol::LegacyJson { .. } => legacy_protocol::version_check(self),
+ Protocol::Postcard { .. } => legacy_protocol::version_check(self),
}
}
@@ -122,6 +161,7 @@ impl ProcMacroServerProcess {
fn enable_rust_analyzer_spans(&self) -> Result<SpanMode, ServerError> {
match self.protocol {
Protocol::LegacyJson { .. } => legacy_protocol::enable_rust_analyzer_spans(self),
+ Protocol::Postcard { .. } => legacy_protocol::enable_rust_analyzer_spans(self),
}
}
@@ -132,21 +172,25 @@ impl ProcMacroServerProcess {
) -> Result<Result<Vec<(String, ProcMacroKind)>, String>, ServerError> {
match self.protocol {
Protocol::LegacyJson { .. } => legacy_protocol::find_proc_macros(self, dylib_path),
+ Protocol::Postcard { .. } => legacy_protocol::find_proc_macros(self, dylib_path),
}
}
- pub(crate) fn send_task<Request, Response>(
+ pub(crate) fn send_task<Request, Response, Buf>(
&self,
serialize_req: impl FnOnce(
&mut dyn Write,
&mut dyn BufRead,
Request,
- &mut String,
+ &mut Buf,
) -> Result<Option<Response>, ServerError>,
req: Request,
- ) -> Result<Response, ServerError> {
+ ) -> Result<Response, ServerError>
+ where
+ Buf: Default,
+ {
let state = &mut *self.state.lock().unwrap();
- let mut buf = String::new();
+ let mut buf = Buf::default();
serialize_req(&mut state.stdin, &mut state.stdout, req, &mut buf)
.and_then(|res| {
res.ok_or_else(|| {
@@ -203,8 +247,9 @@ impl Process {
env: impl IntoIterator<
Item = (impl AsRef<std::ffi::OsStr>, &'a Option<impl 'a + AsRef<std::ffi::OsStr>>),
>,
+ protocol: &Protocol,
) -> io::Result<Process> {
- let child = JodChild(mk_child(path, env)?);
+ let child = JodChild(mk_child(path, env, protocol)?);
Ok(Process { child })
}
@@ -224,9 +269,15 @@ fn mk_child<'a>(
extra_env: impl IntoIterator<
Item = (impl AsRef<std::ffi::OsStr>, &'a Option<impl 'a + AsRef<std::ffi::OsStr>>),
>,
+ protocol: &Protocol,
) -> io::Result<Child> {
#[allow(clippy::disallowed_methods)]
let mut cmd = Command::new(path);
+ if matches!(protocol, Protocol::LegacyJson { .. }) {
+ cmd.args(["--format", "json"]);
+ } else {
+ cmd.args(["--format", "postcard"]);
+ }
for env in extra_env {
match env {
(key, Some(val)) => cmd.env(key, val),
diff --git a/crates/proc-macro-srv-cli/Cargo.toml b/crates/proc-macro-srv-cli/Cargo.toml
index dd31e74915..aa153897fa 100644
--- a/crates/proc-macro-srv-cli/Cargo.toml
+++ b/crates/proc-macro-srv-cli/Cargo.toml
@@ -14,14 +14,13 @@ publish = false
proc-macro-srv.workspace = true
proc-macro-api.workspace = true
tt.workspace = true
+postcard.workspace = true
clap = {version = "4.5.42", default-features = false, features = ["std"]}
-postcard = { version = "1.1.3", optional = true }
[features]
-default = ["postcard"]
+default = []
sysroot-abi = ["proc-macro-srv/sysroot-abi", "proc-macro-api/sysroot-abi"]
in-rust-tree = ["proc-macro-srv/in-rust-tree", "sysroot-abi"]
-postcard = ["dep:postcard"]
[[bin]]
diff --git a/crates/proc-macro-srv-cli/src/main.rs b/crates/proc-macro-srv-cli/src/main.rs
index 9d74fa637a..b6c38da454 100644
--- a/crates/proc-macro-srv-cli/src/main.rs
+++ b/crates/proc-macro-srv-cli/src/main.rs
@@ -51,26 +51,23 @@ fn main() -> std::io::Result<()> {
#[derive(Copy, Clone)]
enum ProtocolFormat {
Json,
- #[cfg(feature = "postcard")]
Postcard,
}
impl ValueEnum for ProtocolFormat {
fn value_variants<'a>() -> &'a [Self] {
- &[ProtocolFormat::Json]
+ &[ProtocolFormat::Json, ProtocolFormat::Postcard]
}
fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
match self {
ProtocolFormat::Json => Some(clap::builder::PossibleValue::new("json")),
- #[cfg(feature = "postcard")]
ProtocolFormat::Postcard => Some(clap::builder::PossibleValue::new("postcard")),
}
}
fn from_str(input: &str, _ignore_case: bool) -> Result<Self, String> {
match input {
"json" => Ok(ProtocolFormat::Json),
- #[cfg(feature = "postcard")]
"postcard" => Ok(ProtocolFormat::Postcard),
_ => Err(format!("unknown protocol format: {input}")),
}
diff --git a/crates/proc-macro-srv-cli/src/main_loop.rs b/crates/proc-macro-srv-cli/src/main_loop.rs
index 5533107570..029ab6eca9 100644
--- a/crates/proc-macro-srv-cli/src/main_loop.rs
+++ b/crates/proc-macro-srv-cli/src/main_loop.rs
@@ -2,19 +2,20 @@
use std::io;
use proc_macro_api::{
+ Codec,
legacy_protocol::{
- json::{read_json, write_json},
+ json::JsonProtocol,
msg::{
self, ExpandMacroData, ExpnGlobals, Message, SpanMode, SpanTransformer,
deserialize_span_data_index_map, serialize_span_data_index_map,
},
+ postcard::PostcardProtocol,
},
version::CURRENT_API_VERSION,
};
use proc_macro_srv::{EnvSnapshot, SpanId};
use crate::ProtocolFormat;
-
struct SpanTrans;
impl SpanTransformer for SpanTrans {
@@ -36,13 +37,12 @@ impl SpanTransformer for SpanTrans {
pub(crate) fn run(format: ProtocolFormat) -> io::Result<()> {
match format {
- ProtocolFormat::Json => run_json(),
- #[cfg(feature = "postcard")]
- ProtocolFormat::Postcard => unimplemented!(),
+ ProtocolFormat::Json => run_::<JsonProtocol>(),
+ ProtocolFormat::Postcard => run_::<PostcardProtocol>(),
}
}
-fn run_json() -> io::Result<()> {
+fn run_<C: Codec>() -> io::Result<()> {
fn macro_kind_to_api(kind: proc_macro_srv::ProcMacroKind) -> proc_macro_api::ProcMacroKind {
match kind {
proc_macro_srv::ProcMacroKind::CustomDerive => {
@@ -53,9 +53,9 @@ fn run_json() -> io::Result<()> {
}
}
- let mut buf = String::new();
- let mut read_request = || msg::Request::read(read_json, &mut io::stdin().lock(), &mut buf);
- let write_response = |msg: msg::Response| msg.write(write_json, &mut io::stdout().lock());
+ let mut buf = C::Buf::default();
+ let mut read_request = || msg::Request::read::<_, C>(&mut io::stdin().lock(), &mut buf);
+ let write_response = |msg: msg::Response| msg.write::<_, C>(&mut io::stdout().lock());
let env = EnvSnapshot::default();
let srv = proc_macro_srv::ProcMacroSrv::new(&env);