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}