rabbitmesh_macros/
lib.rs

1//! # RabbitMesh Macros - The Magic Behind Zero-Port Microservices ✨
2//!
3//! **Procedural macros that transform simple Rust structs into complete microservices with automatic route generation and RabbitMQ RPC integration.**
4//!
5//! This crate provides the three core macros that make RabbitMesh's zero-configuration philosophy possible:
6//! - `#[service_definition]` - Marks a struct as a RabbitMesh service  
7//! - `#[service_impl]` - Processes impl blocks to auto-register methods
8//! - `#[service_method]` - Defines HTTP routes and RPC handlers
9//!
10//! ## 🪄 The Magic
11//!
12//! Write this simple code:
13//!
14//! ```rust,ignore
15//! use rabbitmesh_macros::{service_definition, service_impl};
16//! use serde::{Deserialize, Serialize};
17//!
18//! #[derive(Deserialize)]
19//! pub struct CreateUserRequest {
20//!     pub name: String,
21//!     pub email: String,
22//! }
23//!
24//! #[derive(Serialize)]
25//! pub struct UserResponse {
26//!     pub success: bool,
27//!     pub message: String,
28//!     pub user_id: Option<String>,
29//! }
30//!
31//! #[service_definition]
32//! pub struct UserService;
33//!
34//! #[service_impl]
35//! impl UserService {
36//!     #[service_method("POST /users")]
37//!     pub async fn create_user(request: CreateUserRequest) -> Result<UserResponse, String> {
38//!         // JUST YOUR BUSINESS LOGIC!
39//!         println!("Creating user: {}", request.name);
40//!         Ok(UserResponse {
41//!             success: true,
42//!             message: "User created successfully".to_string(),
43//!             user_id: Some("user123".to_string()),
44//!         })
45//!     }
46//!
47//!     #[service_method("GET /users/:id")]
48//!     pub async fn get_user(user_id: String) -> Result<UserResponse, String> {
49//!         // Framework auto-extracts user_id from URL path
50//!         println!("Getting user: {}", user_id);
51//!         Ok(UserResponse {
52//!             success: true,
53//!             message: format!("Retrieved user {}", user_id),
54//!             user_id: Some(user_id),
55//!         })
56//!     }
57//! }
58//! ```
59//!
60//! **And get all this automatically generated:**
61//! - ✅ HTTP routes: `POST /users`, `GET /users/:id`
62//! - ✅ RabbitMQ RPC handlers: `rabbitmesh.UserService.create_user`, `rabbitmesh.UserService.get_user`
63//! - ✅ Service registration methods: `UserService::create_service()`, `UserService::service_name()`
64//! - ✅ Route discovery: `UserService::get_routes()`
65//! - ✅ JSON serialization/deserialization 
66//! - ✅ API Gateway integration
67//! - ✅ Service discovery
68//!
69//! ## 🎯 Supported Method Patterns
70//!
71//! The macros intelligently handle different method signatures:
72//!
73//! ```rust,ignore
74//! # use rabbitmesh_macros::{service_definition, service_impl};
75//! # use serde::{Deserialize, Serialize};
76//! # #[derive(Deserialize)] pub struct CreateRequest { pub name: String }
77//! # #[derive(Deserialize)] pub struct UpdateRequest { pub name: String }
78//! # #[derive(Serialize)] pub struct Response { pub success: bool }
79//! # #[service_definition] pub struct MyService;
80//! #[service_impl]
81//! impl MyService {
82//!     // Simple path parameter
83//!     #[service_method("GET /items/:id")]
84//!     async fn get_item(id: String) -> Result<Response, String> {
85//!         // id auto-extracted from URL
86//!         Ok(Response { success: true })
87//!     }
88//!
89//!     // Request body
90//!     #[service_method("POST /items")]
91//!     async fn create_item(request: CreateRequest) -> Result<Response, String> {
92//!         // request auto-deserialized from JSON
93//!         Ok(Response { success: true })
94//!     }
95//!
96//!     // Path param + request body (tuple)
97//!     #[service_method("PUT /items/:id")]
98//!     async fn update_item(params: (String, UpdateRequest)) -> Result<Response, String> {
99//!         let (id, request) = params;
100//!         Ok(Response { success: true })
101//!     }
102//!
103//!     // Multiple path parameters
104//!     #[service_method("GET /users/:user_id/items/:item_id")]
105//!     async fn get_user_item(params: (String, String)) -> Result<Response, String> {
106//!         let (user_id, item_id) = params;
107//!         Ok(Response { success: true })
108//!     }
109//! }
110//! ```
111
112extern crate proc_macro;
113
114mod service_definition;
115mod service_method;
116mod service_impl;
117mod registry;
118
119use proc_macro::TokenStream;
120
121/// Marks a struct as a microservice definition.
122/// 
123/// This macro registers the service with the global service registry
124/// and generates the necessary boilerplate for RPC handling.
125#[proc_macro_attribute]
126pub fn service_definition(args: TokenStream, input: TokenStream) -> TokenStream {
127    service_definition::impl_service_definition(args, input)
128}
129
130/// Marks a method as a service endpoint with optional HTTP route information.
131///
132/// The route string is used by the API gateway to generate REST endpoints.
133/// If no route is provided, only RPC calls will be supported.
134///
135/// ## Examples
136///
137/// ```rust,ignore
138/// #[service_method("GET /users/:id")]
139/// pub async fn get_user(user_id: u32) -> Result<User, String> { ... }
140///
141/// #[service_method("POST /users")]
142/// pub async fn create_user(data: CreateUserRequest) -> Result<User, String> { ... }
143///
144/// #[service_method] // RPC only
145/// pub async fn internal_cleanup() -> Result<(), String> { ... }
146/// ```
147#[proc_macro_attribute]
148pub fn service_method(args: TokenStream, input: TokenStream) -> TokenStream {
149    service_method::impl_service_method(args, input)
150}
151
152/// Processes an entire impl block and auto-generates RPC handler registration.
153/// 
154/// This is the advanced version that automatically discovers all #[service_method] 
155/// functions and generates the complete handler registration code.
156///
157/// ## Example
158/// 
159/// ```rust,ignore
160/// #[service_definition]
161/// pub struct UserService;
162///
163/// #[service_impl]
164/// impl UserService {
165///     #[service_method("GET /users/:id")]
166///     pub async fn get_user(user_id: u32) -> Result<User, String> { ... }
167/// }
168/// ```
169#[proc_macro_attribute]
170pub fn service_impl(args: TokenStream, input: TokenStream) -> TokenStream {
171    service_impl::impl_service_impl(args, input)
172}