wrpc_transport_derive_macro/
lib.rs

1//! This crate contains derive macros that enable Rust types to derive [`wrpc_transport::Encode`] and [`wrpc_transport::Receive`] traits.
2//!
3//! This crate is intended to be used via `wrpc-transport-derive`, the umbrella crate which hosts dependencies required by this (internal) macro crate.
4//!
5//! # Example
6//!
7//! ```rust,ignore
8//! use wrpc_transport_derive::{Encode, Receive};
9//!
10//! #[derive(Trace, PartialEq, Eq, Encode, Receive, Default)]
11//! struct TestStruct {
12//!     one: u32,
13//! }
14//!
15//! let mut buffer: Vec<u8> = Vec::new();
16//! // Encode the TestStruct
17//! TestStruct { one: 1 }
18//!     .encode(&mut buffer)
19//!     .await
20//!     .context("failed to perform encode")?;
21//!
22//! // Attempt to receive the value
23//! let (received, leftover): (TestStruct, _) =
24//!     Receive::receive_sync(Bytes::from(buffer), &mut empty())
25//!         .await
26//!         .context("failed to receive")?;
27//!
28//! // At this point, we expect the received bytes to be exactly the same as what we started with
29//! assert_eq!(received, TestStruct { one: 1 }, "received matches");
30//! assert_eq!(leftover.remaining(), 0, "payload was completely consumed");
31//! ```
32//!
33//! NOTE: This macro crate uses `tracing`, so if you'd like to see the input & output tokens, prepend your command (ex. `cargo build`) with `RUST_LOG=trace`.
34//!
35use proc_macro2::TokenStream;
36use tracing::trace;
37use tracing_subscriber::EnvFilter;
38
39use crate::wrpc_transport::encode::derive_encode_inner;
40use crate::wrpc_transport::receive::{derive_receive_inner, derive_subscribe_inner};
41
42mod config;
43mod wrpc_transport;
44
45/// Derive an [`wrpc_transport::Encode`] implementation
46#[proc_macro_derive(Encode, attributes(wrpc_transport_derive))]
47pub fn derive_encode(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
48    let _ = tracing_subscriber::fmt()
49        .with_env_filter(EnvFilter::from_default_env())
50        .try_init();
51
52    let input = TokenStream::from(input);
53    trace!("derive(wrpc_transport::Encode) input:\n---\n{input}\n---");
54
55    let derived = derive_encode_inner(input).expect("failed to perform derive");
56    trace!("derive(wrpc_transport::Encode) output:\n---\n{derived}\n---");
57
58    derived.into()
59}
60
61/// Derive an [`wrpc_transport::Receive`] implementation
62#[proc_macro_derive(Receive, attributes(wrpc_transport_derive))]
63pub fn derive_receive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
64    let _ = tracing_subscriber::fmt()
65        .with_env_filter(EnvFilter::from_default_env())
66        .try_init();
67
68    let input = TokenStream::from(input);
69    trace!("derive(wrpc_transport::Receive) input\n---\n{input}\n---");
70
71    let derived = derive_receive_inner(input).expect("failed to perform derive");
72    trace!("derive(wrpc_transport::Receive) output:\n---\n{derived}\n---");
73
74    derived.into()
75}
76
77/// Derive an [`wrpc_transport::Subscribe`] implementation
78#[proc_macro_derive(Subscribe, attributes(wrpc_transport_derive))]
79pub fn derive_subscribe(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
80    let _ = tracing_subscriber::fmt()
81        .with_env_filter(EnvFilter::from_default_env())
82        .try_init();
83
84    let input = TokenStream::from(input);
85    trace!("derive(wrpc_transport::Subscribe) input\n---\n{input}\n---");
86
87    let derived = derive_subscribe_inner(input).expect("failed to perform derive");
88    trace!("derive(wrpc_transport::Subscribe) output:\n---\n{derived}\n---");
89
90    derived.into()
91}