glue_derive/
lib.rs

1//! This entire crate is literally just for these two macros but represents so much pain and suffering.
2//!
3//! On the user-side there's nothing here you need to worry about here other than:
4//!
5//! #[derive(JsonToFromZMQ, ...)]
6//! pub struct FormMsg {
7//!     ...,
8//! }
9//!
10
11#[macro_use]
12extern crate quote;
13extern crate proc_macro;
14extern crate syn;
15use proc_macro::TokenStream;
16use syn::DeriveInput;
17
18#[proc_macro_derive(JsonToFromZMQ)]
19/// A macro to automatically implement the `JsonSerializeDeserialize` trait and related conversions for specified message types.
20/// This macro generates implementations for the following traits:
21/// - `JsonSerializeDeserialize`: Allows the type to be serialized to and deserialized from JSON format.
22/// - `Into<zmq::Message>`: Provides a method to convert the type into a `zmq::Message`.
23/// - `TryFrom<zmq::Message>`: Allows creating an instance of the type from a `zmq::Message`.
24pub fn impl_json_to_from_zmq_message(input: TokenStream) -> TokenStream {
25    let parsed_input: DeriveInput = syn::parse(input).unwrap();
26    let target = parsed_input.ident;
27    quote! {
28        impl JsonSerializeDeserialize for #target {}
29        impl Into<zmq::Message> for #target {
30            fn into(self) -> zmq::Message { zmq::Message::from(&self.into_serialized()) }
31        }
32        impl TryFrom<zmq::Message> for #target {
33            type Error = serde_json::Error;
34            fn try_from(msg: zmq::Message) -> Result<Self, Self::Error> {
35                Self::try_from_serialized(msg.as_str().ok_or_else(|| Error::custom("Failed to deserialize into string."))?)
36            }
37        }
38    }.into()
39}
40
41#[proc_macro_derive(ByteArrayToFromZMQ)]
42/// A macro to automatically implement the `ByteArraySerializeDeserialize` trait and related conversions for specified message types.
43/// This macro generates implementations for the following traits:
44/// - `ByteArraySerializeDeserialize`: Allows the type to be serialized to and deserialized from JSON format.
45/// - `Into<zmq::Message>`: Provides a method to convert the type into a `zmq::Message`.
46/// - `TryFrom<zmq::Message>`: Allows creating an instance of the type from a `zmq::Message`.
47pub fn impl_byte_array_to_from_zmq_message(input: TokenStream) -> TokenStream {
48    let parsed_input: DeriveInput = syn::parse(input).unwrap();
49    let target = parsed_input.ident;
50    quote! {
51        impl ByteArraySerializeDeserialize for #target {}
52        impl Into<zmq::Message> for #target {
53            fn into(self) -> zmq::Message { zmq::Message::from(&self.into_serialized()) }
54        }
55        impl TryFrom<zmq::Message> for #target {
56            type Error = bincode::Error;
57            fn try_from(msg: zmq::Message) -> Result<Self, Self::Error> { Self::try_from_serialized(msg.to_vec()) }
58        }
59    }.into()
60}