1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
//! # Zenobuf Macros - Procedural macros for the Zenobuf framework
//!
//! This crate provides procedural macros that simplify working with the Zenobuf framework,
//! particularly for integrating Protocol Buffer messages with the type-safe messaging system.
//!
//! ## Overview
//!
//! The main macro provided is [`ZenobufMessage`], which automatically implements the
//! [`zenobuf_core::Message`] trait for Protocol Buffer messages generated by Prost.
//!
//! ## Quick Start
//!
//! ### 1. Add to your `Cargo.toml`
//!
//! ```toml
//! [dependencies]
//! zenobuf-core = "0.2"
//! zenobuf-macros = "0.2"
//! prost = "0.13"
//!
//! [build-dependencies]
//! prost-build = "0.13"
//! ```
//!
//! ### 2. Setup automatic derive in `build.rs`
//!
//! ```rust,ignore
//! fn main() -> std::io::Result<()> {
//! prost_build::Config::new()
//! .type_attribute(".", "#[derive(zenobuf_macros::ZenobufMessage)]")
//! .compile_protos(&["protos/messages.proto"], &["protos"])?;
//! Ok(())
//! }
//! ```
//!
//! ### 3. Use in your code
//!
//! ```rust,ignore
//! // Generated protobuf code automatically has ZenobufMessage derived
//! pub mod proto {
//! include!(concat!(env!("OUT_DIR"), "/my_messages.rs"));
//! }
//!
//! use zenobuf_core::Node;
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let node = Node::new("my_node").await?;
//!
//! // Your protobuf messages now work seamlessly with Zenobuf
//! let publisher = node
//! .publisher::<proto::MyMessage>("topic")
//! .build()
//! .await?;
//!
//! Ok(())
//! }
//! ```
//!
//! ## Manual Usage
//!
//! You can also manually derive the macro on your own types:
//!
//! ```rust,ignore
//! use zenobuf_macros::ZenobufMessage;
//!
//! #[derive(Clone, PartialEq, Default, ZenobufMessage)]
//! pub struct MyMessage {
//! pub value: i32,
//! }
//! ```
//!
//! ## What the Macro Does
//!
//! The `ZenobufMessage` derive macro implements the [`zenobuf_core::Message`] trait,
//! which provides:
//! - Type name information for debugging and introspection
//! - Integration with Zenobuf's type-safe messaging system
//! - Automatic serialization/deserialization support
//!
//! ## Requirements
//!
//! Types that derive `ZenobufMessage` must also implement:
//! - `Clone`
//! - `PartialEq`
//! - `Default`
//! - `prost::Message` (for Protocol Buffer types)
//! - `Send + Sync + 'static` (automatically satisfied by most types)
use TokenStream;
use quote;
use ;
/// Derives the [`zenobuf_core::Message`] trait for Protocol Buffer messages
///
/// This macro automatically implements the [`zenobuf_core::Message`] trait for Protocol
/// Buffer messages generated by Prost. It extracts the type name from the struct name
/// and implements the required methods for integration with Zenobuf's messaging system.
///
/// # Requirements
///
/// The type must implement:
/// - `Clone`
/// - `PartialEq`
/// - `Default`
/// - `prost::Message` (for Protocol Buffer types)
/// - `Send + Sync + 'static`
///
/// # Examples
///
/// ## Manual Usage
///
/// ```rust,ignore
/// use zenobuf_macros::ZenobufMessage;
///
/// #[derive(Clone, PartialEq, Default, ZenobufMessage)]
/// pub struct Point {
/// pub x: f32,
/// pub y: f32,
/// pub z: f32,
/// }
/// ```
///
/// ## With Protocol Buffers (typical usage)
///
/// In your `build.rs`:
/// ```rust,ignore
/// prost_build::Config::new()
/// .type_attribute(".", "#[derive(zenobuf_macros::ZenobufMessage)]")
/// .compile_protos(&["protos/messages.proto"], &["protos"])?;
/// # Ok::<(), std::io::Error>(())
/// ```
///
/// This automatically adds the derive macro to all generated Protocol Buffer types.
///
/// ## Using with Zenobuf
///
/// ```rust,ignore
/// use zenobuf_core::Node;
///
/// #[tokio::main]
/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let node = Node::new("publisher").await?;
///
/// // Point now implements Message and can be used with publishers
/// let publisher = node
/// .publisher::<Point>("points")
/// .build()
/// .await?;
///
/// let point = Point { x: 1.0, y: 2.0, z: 3.0 };
/// publisher.publish(&point)?;
///
/// Ok(())
/// }
/// ```
///
/// # Generated Implementation
///
/// The macro generates an implementation like this:
///
/// ```rust,ignore
/// impl zenobuf_core::Message for Point {
/// fn type_name() -> &'static str {
/// "Point"
/// }
/// }
/// ```