hyperlane_macros/lib.rs
1//! # Hyperlane Macros
2//!
3//! A comprehensive collection of procedural macros for building HTTP servers with enhanced functionality.
4//! This crate provides attribute macros that simplify HTTP request handling, protocol validation,
5//! response management, and request data extraction.
6//!
7//! ## Features
8//!
9//! - **HTTP Method Handlers**: Macros for all standard HTTP methods (GET, POST, PUT, DELETE, etc.)
10//! - **Protocol Validation**: Support for HTTP versions, WebSocket, TLS, and HTTP/2 cleartext
11//! - **Response Management**: Status code setting, reason phrase customization, and response sending
12//! - **Request Data Extraction**: Body parsing, request header extraction, request query parameters, and route parameters
13//! - **Filter Mechanisms**: Unknown method, upgrade, and version filtering
14//! - **Hook System**: Pre and post execution hooks for request processing
15//! - **Stream Management**: Connection state handling for aborted and closed streams
16//! - **Server Instance Creation**: Automatic Server instance initialization with custom variable names
17//!
18//! ## Dependencies
19//!
20//! To use this crate, add the following dependencies to your `Cargo.toml`:
21//!
22//! ```toml
23//! [dependencies]
24//! hyperlane-macros = "*"
25//! hyperlane = "*"
26//! serde = { version = "*", features = ["derive"] }
27//! ```
28//!
29//! ## Usage Guidelines
30//!
31//! Most macros are designed to be used as attribute macros on async functions that accept a `Context` parameter.
32//! The `hyperlane` macro can be used on any async function to create a Server instance.
33//! Multiple macros can be combined on a single function to create complex request handling logic.
34//! When using hook macros (`pre_hook`, `post_hook`), avoid combining them with other macros on the same function
35//! to prevent unexpected behavior during macro expansion.
36
37mod aborted;
38mod closed;
39mod common;
40mod filter;
41mod flush;
42mod hook;
43mod http;
44mod protocol;
45mod request;
46mod response;
47mod send;
48mod server;
49
50pub(crate) use aborted::*;
51pub(crate) use closed::*;
52pub(crate) use common::*;
53pub(crate) use filter::*;
54pub(crate) use flush::*;
55pub(crate) use hook::*;
56pub(crate) use http::*;
57pub(crate) use protocol::*;
58pub(crate) use request::*;
59pub(crate) use response::*;
60pub(crate) use send::*;
61pub(crate) use server::*;
62
63pub(crate) use proc_macro::TokenStream;
64pub(crate) use proc_macro2::TokenStream as TokenStream2;
65pub(crate) use quote::quote;
66pub(crate) use syn::{
67 parse::{Parse, ParseStream},
68 punctuated::Punctuated,
69 *,
70};
71
72/// Restricts function execution to HTTP GET requests only.
73///
74/// This attribute macro ensures the decorated function only executes when the incoming request
75/// uses the GET HTTP method. Requests with other methods will be filtered out.
76///
77/// # Usage
78///
79/// ```rust
80/// use hyperlane_macros::*;
81/// use hyperlane::*;
82///
83/// #[get]
84/// async fn handle_get(ctx: Context) {
85/// // Function body
86/// }
87/// ```
88///
89/// The macro takes no parameters and should be applied directly to async functions
90/// that accept a `Context` parameter.
91#[proc_macro_attribute]
92pub fn get(_attr: TokenStream, item: TokenStream) -> TokenStream {
93 get_handler(item)
94}
95
96/// Restricts function execution to HTTP POST requests only.
97///
98/// This attribute macro ensures the decorated function only executes when the incoming request
99/// uses the POST HTTP method. Requests with other methods will be filtered out.
100///
101/// # Usage
102///
103/// ```rust
104/// use hyperlane_macros::*;
105/// use hyperlane::*;
106///
107/// #[post]
108/// async fn handle_post(ctx: Context) {
109/// // Function body
110/// }
111/// ```
112///
113/// The macro takes no parameters and should be applied directly to async functions
114/// that accept a `Context` parameter.
115#[proc_macro_attribute]
116pub fn post(_attr: TokenStream, item: TokenStream) -> TokenStream {
117 post_handler(item)
118}
119
120/// Restricts function execution to HTTP PUT requests only.
121///
122/// This attribute macro ensures the decorated function only executes when the incoming request
123/// uses the PUT HTTP method. Requests with other methods will be filtered out.
124///
125/// # Usage
126///
127/// ```rust
128/// use hyperlane_macros::*;
129/// use hyperlane::*;
130///
131/// #[put]
132/// async fn handle_put(ctx: Context) {
133/// // Function body
134/// }
135/// ```
136///
137/// The macro takes no parameters and should be applied directly to async functions
138/// that accept a `Context` parameter.
139#[proc_macro_attribute]
140pub fn put(_attr: TokenStream, item: TokenStream) -> TokenStream {
141 put_handler(item)
142}
143
144/// Restricts function execution to HTTP DELETE requests only.
145///
146/// This attribute macro ensures the decorated function only executes when the incoming request
147/// uses the DELETE HTTP method. Requests with other methods will be filtered out.
148///
149/// # Usage
150///
151/// ```rust
152/// use hyperlane_macros::*;
153/// use hyperlane::*;
154///
155/// #[delete]
156/// async fn handle_delete(ctx: Context) {
157/// // Function body
158/// }
159/// ```
160///
161/// The macro takes no parameters and should be applied directly to async functions
162/// that accept a `Context` parameter.
163#[proc_macro_attribute]
164pub fn delete(_attr: TokenStream, item: TokenStream) -> TokenStream {
165 delete_handler(item)
166}
167
168/// Restricts function execution to HTTP PATCH requests only.
169///
170/// This attribute macro ensures the decorated function only executes when the incoming request
171/// uses the PATCH HTTP method. Requests with other methods will be filtered out.
172///
173/// # Usage
174///
175/// ```rust
176/// use hyperlane_macros::*;
177/// use hyperlane::*;
178///
179/// #[patch]
180/// async fn handle_patch(ctx: Context) {
181/// // Function body
182/// }
183/// ```
184///
185/// The macro takes no parameters and should be applied directly to async functions
186/// that accept a `Context` parameter.
187#[proc_macro_attribute]
188pub fn patch(_attr: TokenStream, item: TokenStream) -> TokenStream {
189 patch_handler(item)
190}
191
192/// Restricts function execution to HTTP HEAD requests only.
193///
194/// This attribute macro ensures the decorated function only executes when the incoming request
195/// uses the HEAD HTTP method. Requests with other methods will be filtered out.
196///
197/// # Usage
198///
199/// ```rust
200/// use hyperlane_macros::*;
201/// use hyperlane::*;
202///
203/// #[head]
204/// async fn handle_head(ctx: Context) {
205/// // Function body
206/// }
207/// ```
208///
209/// The macro takes no parameters and should be applied directly to async functions
210/// that accept a `Context` parameter.
211#[proc_macro_attribute]
212pub fn head(_attr: TokenStream, item: TokenStream) -> TokenStream {
213 head_handler(item)
214}
215
216/// Restricts function execution to HTTP OPTIONS requests only.
217///
218/// This attribute macro ensures the decorated function only executes when the incoming request
219/// uses the OPTIONS HTTP method. Requests with other methods will be filtered out.
220///
221/// # Usage
222///
223/// ```rust
224/// use hyperlane_macros::*;
225/// use hyperlane::*;
226///
227/// #[options]
228/// async fn handle_options(ctx: Context) {
229/// // Function body
230/// }
231/// ```
232///
233/// The macro takes no parameters and should be applied directly to async functions
234/// that accept a `Context` parameter.
235#[proc_macro_attribute]
236pub fn options(_attr: TokenStream, item: TokenStream) -> TokenStream {
237 options_handler(item)
238}
239
240/// Restricts function execution to HTTP CONNECT requests only.
241///
242/// This attribute macro ensures the decorated function only executes when the incoming request
243/// uses the CONNECT HTTP method. Requests with other methods will be filtered out.
244///
245/// # Usage
246///
247/// ```rust
248/// use hyperlane_macros::*;
249/// use hyperlane::*;
250///
251/// #[connect]
252/// async fn handle_connect(ctx: Context) {
253/// // Function body
254/// }
255/// ```
256///
257/// The macro takes no parameters and should be applied directly to async functions
258/// that accept a `Context` parameter.
259#[proc_macro_attribute]
260pub fn connect(_attr: TokenStream, item: TokenStream) -> TokenStream {
261 connect_handler(item)
262}
263
264/// Restricts function execution to HTTP TRACE requests only.
265///
266/// This attribute macro ensures the decorated function only executes when the incoming request
267/// uses the TRACE HTTP method. Requests with other methods will be filtered out.
268///
269/// # Usage
270///
271/// ```rust
272/// use hyperlane_macros::*;
273/// use hyperlane::*;
274///
275/// #[trace]
276/// async fn handle_trace(ctx: Context) {
277/// // Function body
278/// }
279/// ```
280///
281/// The macro takes no parameters and should be applied directly to async functions
282/// that accept a `Context` parameter.
283#[proc_macro_attribute]
284pub fn trace(_attr: TokenStream, item: TokenStream) -> TokenStream {
285 trace_handler(item)
286}
287
288/// Allows function to handle multiple HTTP methods.
289///
290/// This attribute macro configures the decorated function to execute for any of the specified
291/// HTTP methods. Methods should be provided as a comma-separated list.
292///
293/// # Usage
294///
295/// ```rust
296/// use hyperlane_macros::*;
297/// use hyperlane::*;
298///
299/// #[methods(get, post)]
300/// async fn handle_get_post(ctx: Context) {
301/// // Function body
302/// }
303///
304/// #[methods(put, patch, delete)]
305/// async fn handle_modifications(ctx: Context) {
306/// // Function body
307/// }
308/// ```
309///
310/// The macro accepts a comma-separated list of HTTP method names (lowercase) and should be
311/// applied to async functions that accept a `Context` parameter.
312#[proc_macro_attribute]
313pub fn methods(attr: TokenStream, item: TokenStream) -> TokenStream {
314 methods_macro(attr, item)
315}
316
317/// Restricts function execution to WebSocket upgrade requests only.
318///
319/// This attribute macro ensures the decorated function only executes when the incoming request
320/// is a valid WebSocket upgrade request with proper request headers and protocol negotiation.
321///
322/// # Usage
323///
324/// ```rust
325/// use hyperlane_macros::*;
326/// use hyperlane::*;
327///
328/// #[ws]
329/// async fn handle_websocket(ctx: Context) {
330/// // WebSocket handling logic
331/// }
332/// ```
333///
334/// The macro takes no parameters and should be applied directly to async functions
335/// that accept a `Context` parameter.
336#[proc_macro_attribute]
337pub fn ws(_attr: TokenStream, item: TokenStream) -> TokenStream {
338 ws_macro(item)
339}
340
341/// Restricts function execution to standard HTTP requests only.
342///
343/// This attribute macro ensures the decorated function only executes for standard HTTP requests,
344/// excluding WebSocket upgrades and other protocol upgrade requests.
345///
346/// # Usage
347///
348/// ```rust
349/// use hyperlane_macros::*;
350/// use hyperlane::*;
351///
352/// #[http]
353/// async fn handle_http(ctx: Context) {
354/// // HTTP request handling logic
355/// }
356/// ```
357///
358/// The macro takes no parameters and should be applied directly to async functions
359/// that accept a `Context` parameter.
360#[proc_macro_attribute]
361pub fn http(_attr: TokenStream, item: TokenStream) -> TokenStream {
362 http_macro(item)
363}
364
365/// Sets the HTTP status code for the response.
366///
367/// This attribute macro configures the HTTP status code that will be sent with the response.
368/// The status code can be provided as a numeric literal or a global constant.
369///
370/// # Usage
371///
372/// ```rust
373/// use hyperlane_macros::*;
374/// use hyperlane::*;
375///
376/// const CUSTOM_STATUS: i32 = 418;
377///
378/// #[response_status_code(200)]
379/// async fn success_handler(ctx: Context) {
380/// // Response will have status code 200
381/// }
382///
383/// #[response_status_code(404)]
384/// async fn not_found_handler(ctx: Context) {
385/// // Response will have status code 404
386/// }
387///
388/// #[response_status_code(CUSTOM_STATUS)]
389/// async fn custom_handler(ctx: Context) {
390/// // Response will have status code from global constant
391/// }
392/// ```
393///
394/// The macro accepts a numeric HTTP status code (e.g., 200, 404, 500) or a global constant
395/// and should be applied to async functions that accept a `Context` parameter.
396#[proc_macro_attribute]
397pub fn response_status_code(attr: TokenStream, item: TokenStream) -> TokenStream {
398 response_status_code_macro(attr, item)
399}
400
401/// Sets the HTTP reason phrase for the response.
402///
403/// This attribute macro configures the HTTP reason phrase that accompanies the status code.
404/// The reason phrase can be provided as a string literal or a global constant.
405///
406/// # Usage
407///
408/// ```rust
409/// use hyperlane_macros::*;
410/// use hyperlane::*;
411///
412/// const CUSTOM_REASON: &str = "I'm a teapot";
413///
414/// #[response_reason_phrase("OK")]
415/// async fn success_handler(ctx: Context) {
416/// // Response will have reason phrase "OK"
417/// }
418///
419/// #[response_reason_phrase("Not Found")]
420/// async fn not_found_handler(ctx: Context) {
421/// // Response will have reason phrase "Not Found"
422/// }
423///
424/// #[response_reason_phrase(CUSTOM_REASON)]
425/// async fn custom_handler(ctx: Context) {
426/// // Response will have reason phrase from global constant
427/// }
428/// ```
429///
430/// The macro accepts a string literal or global constant for the reason phrase and should be
431/// applied to async functions that accept a `Context` parameter.
432#[proc_macro_attribute]
433pub fn response_reason_phrase(attr: TokenStream, item: TokenStream) -> TokenStream {
434 response_reason_phrase_macro(attr, item)
435}
436
437/// Sets a specific HTTP response header.
438///
439/// This attribute macro configures a specific HTTP response header that will be sent with the response.
440/// Both the header name and value can be provided as string literals or global constants.
441///
442/// # Usage
443///
444/// ```rust
445/// use hyperlane_macros::*;
446/// use hyperlane::*;
447///
448/// const HEADER_NAME: &str = "X-Custom-Header";
449/// const HEADER_VALUE: &str = "custom-value";
450///
451/// #[response_header("Content-Type" => "application/json")]
452/// async fn json_handler(ctx: Context) {
453/// // Response will have Content-Type header set to application/json
454/// }
455///
456/// #[response_header("X-Static-Header" => "static-value")]
457/// async fn static_header_handler(ctx: Context) {
458/// // Response will have static header
459/// }
460///
461/// #[response_header(HEADER_NAME => HEADER_VALUE)]
462/// async fn dynamic_header_handler(ctx: Context) {
463/// // Response will have header from global constants
464/// }
465/// ```
466///
467/// The macro accepts two parameters: header name and header value, both can be string literals
468/// or global constants. Should be applied to async functions that accept a `Context` parameter.
469#[proc_macro_attribute]
470pub fn response_header(attr: TokenStream, item: TokenStream) -> TokenStream {
471 response_header_macro(attr, item)
472}
473
474/// Sets the HTTP response body.
475///
476/// This attribute macro configures the HTTP response body that will be sent with the response.
477/// The body content can be provided as a string literal or a global constant.
478///
479/// # Usage
480///
481/// ```rust
482/// use hyperlane_macros::*;
483/// use hyperlane::*;
484///
485/// const RESPONSE_DATA: &str = "Dynamic content from constant";
486///
487/// #[response_body("Hello, World!")]
488/// async fn hello_handler(ctx: Context) {
489/// // Response will have body "Hello, World!"
490/// }
491///
492/// #[response_body("{\"message\": \"success\"}")]
493/// async fn json_response_handler(ctx: Context) {
494/// // Response will have JSON body
495/// }
496///
497/// #[response_body(RESPONSE_DATA)]
498/// async fn dynamic_body_handler(ctx: Context) {
499/// // Response will have body from global constant
500/// }
501/// ```
502///
503/// The macro accepts a string literal or global constant for the response body and should be
504/// applied to async functions that accept a `Context` parameter.
505#[proc_macro_attribute]
506pub fn response_body(attr: TokenStream, item: TokenStream) -> TokenStream {
507 response_body_macro(attr, item)
508}
509
510/// Automatically sends the complete response after function execution.
511///
512/// This attribute macro ensures that the response (request headers and body) is automatically sent
513/// to the client after the function completes execution.
514///
515/// # Usage
516///
517/// ```rust
518/// use hyperlane_macros::*;
519/// use hyperlane::*;
520///
521/// #[send]
522/// async fn auto_send_handler(ctx: Context) {
523/// let _ = ctx.set_response_body("Hello World").await;
524/// // Response is automatically sent after function returns
525/// }
526/// ```
527///
528/// The macro takes no parameters and should be applied directly to async functions
529/// that accept a `Context` parameter.
530#[proc_macro_attribute]
531pub fn send(_attr: TokenStream, item: TokenStream) -> TokenStream {
532 send_macro(item)
533}
534
535/// Automatically sends only the response body after function execution.
536///
537/// This attribute macro ensures that only the response body is automatically sent
538/// to the client after the function completes, handling request headers separately.
539///
540/// # Usage
541///
542/// ```rust
543/// use hyperlane_macros::*;
544/// use hyperlane::*;
545///
546/// #[send_body]
547/// async fn auto_send_body_handler(ctx: Context) {
548/// let _ = ctx.set_response_body("Response body content").await;
549/// // Only response body is automatically sent after function returns
550/// }
551/// ```
552///
553/// The macro takes no parameters and should be applied directly to async functions
554/// that accept a `Context` parameter.
555#[proc_macro_attribute]
556pub fn send_body(_attr: TokenStream, item: TokenStream) -> TokenStream {
557 send_body_macro(item)
558}
559
560/// Sends the complete response exactly once after function execution.
561///
562/// This attribute macro ensures that the response is sent exactly once to the client,
563/// preventing multiple response transmissions for single-use scenarios.
564///
565/// # Usage
566///
567/// ```rust
568/// use hyperlane_macros::*;
569/// use hyperlane::*;
570///
571/// #[send_once]
572/// async fn send_once_handler(ctx: Context) {
573/// let _ = ctx.set_response_body("One-time response").await;
574/// // Response is sent exactly once after function returns
575/// }
576/// ```
577///
578/// The macro takes no parameters and should be applied directly to async functions
579/// that accept a `Context` parameter.
580#[proc_macro_attribute]
581pub fn send_once(_attr: TokenStream, item: TokenStream) -> TokenStream {
582 send_once_macro(item)
583}
584
585/// Sends only the response body exactly once after function execution.
586///
587/// This attribute macro ensures that the response body is sent exactly once to the client,
588/// preventing multiple body transmissions for single-use scenarios.
589///
590/// # Usage
591///
592/// ```rust
593/// use hyperlane_macros::*;
594/// use hyperlane::*;
595///
596/// #[send_once_body]
597/// async fn send_once_body_handler(ctx: Context) {
598/// let _ = ctx.set_response_body("One-time body content").await;
599/// // Response body is sent exactly once after function returns
600/// }
601/// ```
602///
603/// The macro takes no parameters and should be applied directly to async functions
604/// that accept a `Context` parameter.
605#[proc_macro_attribute]
606pub fn send_once_body(_attr: TokenStream, item: TokenStream) -> TokenStream {
607 send_once_body_macro(item)
608}
609
610/// Flushes the response stream after function execution.
611///
612/// This attribute macro ensures that the response stream is flushed to guarantee immediate
613/// data transmission, forcing any buffered response data to be sent to the client.
614///
615/// # Usage
616///
617/// ```rust
618/// use hyperlane_macros::*;
619/// use hyperlane::*;
620///
621/// #[flush]
622/// async fn flush_handler(ctx: Context) {
623/// let _ = ctx.set_response_body("Immediate response").await;
624/// // Response stream is flushed after function returns
625/// }
626/// ```
627///
628/// The macro takes no parameters and should be applied directly to async functions
629/// that accept a `Context` parameter.
630#[proc_macro_attribute]
631pub fn flush(_attr: TokenStream, item: TokenStream) -> TokenStream {
632 flush_macro(item)
633}
634
635/// Handles aborted request scenarios.
636///
637/// This attribute macro configures the function to handle cases where the client has
638/// aborted the request, providing appropriate handling for interrupted or cancelled requests.
639///
640/// # Usage
641///
642/// ```rust
643/// use hyperlane_macros::*;
644/// use hyperlane::*;
645///
646/// #[aborted]
647/// async fn handle_aborted(ctx: Context) {
648/// // Handle aborted request logic
649/// }
650/// ```
651///
652/// The macro takes no parameters and should be applied directly to async functions
653/// that accept a `Context` parameter.
654#[proc_macro_attribute]
655pub fn aborted(_attr: TokenStream, item: TokenStream) -> TokenStream {
656 aborted_macro(item)
657}
658
659/// Handles closed connection scenarios.
660///
661/// This attribute macro configures the function to handle cases where the connection
662/// has been closed, providing appropriate handling for terminated or disconnected connections.
663///
664/// # Usage
665///
666/// ```rust
667/// use hyperlane_macros::*;
668/// use hyperlane::*;
669///
670/// #[closed]
671/// async fn handle_closed(ctx: Context) {
672/// // Handle closed connection logic
673/// }
674/// ```
675///
676/// The macro takes no parameters and should be applied directly to async functions
677/// that accept a `Context` parameter.
678#[proc_macro_attribute]
679pub fn closed(_attr: TokenStream, item: TokenStream) -> TokenStream {
680 closed_macro(item)
681}
682
683/// Restricts function execution to HTTP/2 Cleartext (h2c) requests only.
684///
685/// This attribute macro ensures the decorated function only executes for HTTP/2 cleartext
686/// requests that use the h2c upgrade mechanism.
687///
688/// # Usage
689///
690/// ```rust
691/// use hyperlane_macros::*;
692/// use hyperlane::*;
693///
694/// #[h2c]
695/// async fn handle_h2c(ctx: Context) {
696/// // Handle HTTP/2 cleartext requests
697/// }
698/// ```
699///
700/// The macro takes no parameters and should be applied directly to async functions
701/// that accept a `Context` parameter.
702#[proc_macro_attribute]
703pub fn h2c(_attr: TokenStream, item: TokenStream) -> TokenStream {
704 h2c_macro(item)
705}
706
707/// Restricts function execution to HTTP/0.9 requests only.
708///
709/// This attribute macro ensures the decorated function only executes for HTTP/0.9
710/// protocol requests, the earliest version of the HTTP protocol.
711///
712/// # Usage
713///
714/// ```rust
715/// use hyperlane_macros::*;
716/// use hyperlane::*;
717///
718/// #[http0_9]
719/// async fn handle_http09(ctx: Context) {
720/// // Handle HTTP/0.9 requests
721/// }
722/// ```
723///
724/// The macro takes no parameters and should be applied directly to async functions
725/// that accept a `Context` parameter.
726#[proc_macro_attribute]
727pub fn http0_9(_attr: TokenStream, item: TokenStream) -> TokenStream {
728 http0_9_macro(item)
729}
730
731/// Restricts function execution to HTTP/1.0 requests only.
732///
733/// This attribute macro ensures the decorated function only executes for HTTP/1.0
734/// protocol requests.
735///
736/// # Usage
737///
738/// ```rust
739/// use hyperlane_macros::*;
740/// use hyperlane::*;
741///
742/// #[http1_0]
743/// async fn handle_http10(ctx: Context) {
744/// // Handle HTTP/1.0 requests
745/// }
746/// ```
747///
748/// The macro takes no parameters and should be applied directly to async functions
749/// that accept a `Context` parameter.
750#[proc_macro_attribute]
751pub fn http1_0(_attr: TokenStream, item: TokenStream) -> TokenStream {
752 http1_0_macro(item)
753}
754
755/// Restricts function execution to HTTP/1.1 requests only.
756///
757/// This attribute macro ensures the decorated function only executes for HTTP/1.1
758/// protocol requests.
759///
760/// # Usage
761///
762/// ```rust
763/// use hyperlane_macros::*;
764/// use hyperlane::*;
765///
766/// #[http1_1]
767/// async fn handle_http11(ctx: Context) {
768/// // Handle HTTP/1.1 requests
769/// }
770/// ```
771///
772/// The macro takes no parameters and should be applied directly to async functions
773/// that accept a `Context` parameter.
774#[proc_macro_attribute]
775pub fn http1_1(_attr: TokenStream, item: TokenStream) -> TokenStream {
776 http1_1_macro(item)
777}
778
779/// Restricts function execution to HTTP/1.1 or higher protocol versions.
780///
781/// This attribute macro ensures the decorated function only executes for HTTP/1.1
782/// or newer protocol versions, including HTTP/2, HTTP/3, and future versions.
783///
784/// # Usage
785///
786/// ```rust
787/// use hyperlane_macros::*;
788/// use hyperlane::*;
789///
790/// #[http1_1_or_higher]
791/// async fn handle_modern_http(ctx: Context) {
792/// // Handle HTTP/1.1, HTTP/2, HTTP/3, etc.
793/// }
794/// ```
795///
796/// The macro takes no parameters and should be applied directly to async functions
797/// that accept a `Context` parameter.
798#[proc_macro_attribute]
799pub fn http1_1_or_higher(_attr: TokenStream, item: TokenStream) -> TokenStream {
800 http1_1_or_higher_macro(item)
801}
802
803/// Restricts function execution to HTTP/2 requests only.
804///
805/// This attribute macro ensures the decorated function only executes for HTTP/2
806/// protocol requests.
807///
808/// # Usage
809///
810/// ```rust
811/// use hyperlane_macros::*;
812/// use hyperlane::*;
813///
814/// #[http2]
815/// async fn handle_http2(ctx: Context) {
816/// // Handle HTTP/2 requests
817/// }
818/// ```
819///
820/// The macro takes no parameters and should be applied directly to async functions
821/// that accept a `Context` parameter.
822#[proc_macro_attribute]
823pub fn http2(_attr: TokenStream, item: TokenStream) -> TokenStream {
824 http2_macro(item)
825}
826
827/// Restricts function execution to HTTP/3 requests only.
828///
829/// This attribute macro ensures the decorated function only executes for HTTP/3
830/// protocol requests, the latest version of the HTTP protocol.
831///
832/// # Usage
833///
834/// ```rust
835/// use hyperlane_macros::*;
836/// use hyperlane::*;
837///
838/// #[http3]
839/// async fn handle_http3(ctx: Context) {
840/// // Handle HTTP/3 requests
841/// }
842/// ```
843///
844/// The macro takes no parameters and should be applied directly to async functions
845/// that accept a `Context` parameter.
846#[proc_macro_attribute]
847pub fn http3(_attr: TokenStream, item: TokenStream) -> TokenStream {
848 http3_macro(item)
849}
850
851/// Restricts function execution to TLS-encrypted requests only.
852///
853/// This attribute macro ensures the decorated function only executes for requests
854/// that use TLS/SSL encryption on the connection.
855///
856/// # Usage
857///
858/// ```rust
859/// use hyperlane_macros::*;
860/// use hyperlane::*;
861///
862/// #[tls]
863/// async fn handle_secure(ctx: Context) {
864/// // Handle TLS-encrypted requests only
865/// }
866/// ```
867///
868/// The macro takes no parameters and should be applied directly to async functions
869/// that accept a `Context` parameter.
870#[proc_macro_attribute]
871pub fn tls(_attr: TokenStream, item: TokenStream) -> TokenStream {
872 tls_macro(item)
873}
874
875/// Handles requests with unknown or non-standard HTTP methods.
876///
877/// This attribute macro configures the function to handle requests that use
878/// unrecognized or unsupported HTTP methods, providing a fallback for non-standard methods.
879///
880/// # Usage
881///
882/// ```rust
883/// use hyperlane_macros::*;
884/// use hyperlane::*;
885///
886/// #[filter_unknown_method]
887/// async fn handle_unknown_method(ctx: Context) {
888/// // Handle requests with unknown HTTP methods
889/// }
890/// ```
891///
892/// The macro takes no parameters and should be applied directly to async functions
893/// that accept a `Context` parameter.
894#[proc_macro_attribute]
895pub fn filter_unknown_method(_attr: TokenStream, item: TokenStream) -> TokenStream {
896 filter_unknown_method_macro(item)
897}
898
899/// Handles requests with unknown or non-standard upgrade protocols.
900///
901/// This attribute macro configures the function to handle requests that specify
902/// unrecognized upgrade protocols, providing a fallback for non-standard upgrade request headers.
903///
904/// # Usage
905///
906/// ```rust
907/// use hyperlane_macros::*;
908/// use hyperlane::*;
909///
910/// #[filter_unknown_upgrade]
911/// async fn handle_unknown_upgrade(ctx: Context) {
912/// // Handle requests with unknown upgrade protocols
913/// }
914/// ```
915///
916/// The macro takes no parameters and should be applied directly to async functions
917/// that accept a `Context` parameter.
918#[proc_macro_attribute]
919pub fn filter_unknown_upgrade(_attr: TokenStream, item: TokenStream) -> TokenStream {
920 filter_unknown_upgrade_macro(item)
921}
922
923/// Handles requests with unknown or non-standard HTTP versions.
924///
925/// This attribute macro configures the function to handle requests that use
926/// unrecognized HTTP protocol versions, providing a fallback for non-standard versions.
927///
928/// # Usage
929///
930/// ```rust
931/// use hyperlane_macros::*;
932/// use hyperlane::*;
933///
934/// #[filter_unknown_version]
935/// async fn handle_unknown_version(ctx: Context) {
936/// // Handle requests with unknown HTTP versions
937/// }
938/// ```
939///
940/// The macro takes no parameters and should be applied directly to async functions
941/// that accept a `Context` parameter.
942#[proc_macro_attribute]
943pub fn filter_unknown_version(_attr: TokenStream, item: TokenStream) -> TokenStream {
944 filter_unknown_version_macro(item)
945}
946
947/// Handles requests with any unknown characteristics.
948///
949/// This attribute macro combines filtering for unknown methods, upgrade protocols, and HTTP versions,
950/// providing comprehensive handling for requests with any unrecognized characteristics.
951///
952/// # Usage
953///
954/// ```rust
955/// use hyperlane_macros::*;
956/// use hyperlane::*;
957///
958/// #[filter_unknown]
959/// async fn handle_all_unknown(ctx: Context) {
960/// // Handle requests with any unknown characteristics
961/// }
962/// ```
963///
964/// The macro takes no parameters and should be applied directly to async functions
965/// that accept a `Context` parameter.
966#[proc_macro_attribute]
967pub fn filter_unknown(_attr: TokenStream, item: TokenStream) -> TokenStream {
968 filter_unknown_macro(item)
969}
970
971/// Executes a specified function before the main handler function.
972///
973/// This attribute macro configures a pre-execution hook that runs before the main function logic.
974/// The specified hook function will be called first, followed by the main function execution.
975///
976/// # Usage
977///
978/// ```rust
979/// use hyperlane_macros::*;
980/// use hyperlane::*;
981///
982/// #[get]
983/// async fn pre_handler(ctx: Context) {
984/// // Pre-execution logic
985/// }
986///
987/// #[pre_hook(pre_handler)]
988/// async fn main_handler(ctx: Context) {
989/// // Main function logic (runs after pre_handler)
990/// }
991/// ```
992///
993/// The macro accepts a function name as parameter. Both the hook function and main function
994/// must accept a `Context` parameter. Avoid combining this macro with other macros on the
995/// same function to prevent macro expansion conflicts.
996#[proc_macro_attribute]
997pub fn pre_hook(attr: TokenStream, item: TokenStream) -> TokenStream {
998 pre_hook_macro(attr, item)
999}
1000
1001/// Executes a specified function after the main handler function.
1002///
1003/// This attribute macro configures a post-execution hook that runs after the main function logic.
1004/// The main function will execute first, followed by the specified hook function.
1005///
1006/// # Usage
1007///
1008/// ```rust
1009/// use hyperlane_macros::*;
1010/// use hyperlane::*;
1011///
1012/// #[send]
1013/// async fn post_handler(ctx: Context) {
1014/// // Post-execution logic
1015/// }
1016///
1017/// #[post_hook(post_handler)]
1018/// async fn main_handler(ctx: Context) {
1019/// // Main function logic (runs before post_handler)
1020/// }
1021/// ```
1022///
1023/// The macro accepts a function name as parameter. Both the hook function and main function
1024/// must accept a `Context` parameter. Avoid combining this macro with other macros on the
1025/// same function to prevent macro expansion conflicts.
1026#[proc_macro_attribute]
1027pub fn post_hook(attr: TokenStream, item: TokenStream) -> TokenStream {
1028 post_hook_macro(attr, item)
1029}
1030
1031/// Parses the request body into a specified variable and type.
1032///
1033/// This attribute macro extracts and deserializes the request body content into a variable
1034/// with the specified type. The body content is typically parsed as JSON.
1035///
1036/// # Usage
1037///
1038/// ```rust
1039/// use hyperlane_macros::*;
1040/// use hyperlane::*;
1041/// use serde::Deserialize;
1042///
1043/// #[derive(Deserialize, Clone)]
1044/// struct UserData {
1045/// name: String,
1046/// age: u32,
1047/// }
1048///
1049/// #[body(user_data: UserData)]
1050/// async fn handle_user(ctx: Context) {
1051/// if let Ok(data) = user_data {
1052/// // Use the parsed user data
1053/// }
1054/// }
1055/// ```
1056///
1057/// The macro accepts a variable name and type in the format `variable_name: Type`.
1058/// The variable will be available in the function scope as a `Result<Type, Error>`.
1059#[proc_macro_attribute]
1060pub fn body(attr: TokenStream, item: TokenStream) -> TokenStream {
1061 body_macro(attr, item)
1062}
1063
1064/// Extracts a specific attribute value into a variable.
1065///
1066/// This attribute macro retrieves a specific attribute by key and makes it available
1067/// as a typed variable from the request context.
1068///
1069/// # Usage
1070///
1071/// ```rust
1072/// use hyperlane_macros::*;
1073/// use hyperlane::*;
1074/// use serde::Deserialize;
1075///
1076/// const USER_KEY: &str = "user_data";
1077///
1078/// #[derive(Deserialize, Clone)]
1079/// struct User {
1080/// id: u64,
1081/// name: String,
1082/// }
1083///
1084/// #[attribute(USER_KEY => user: User)]
1085/// async fn handle_with_attribute(ctx: Context) {
1086/// if let Some(user_data) = user {
1087/// // Use the extracted attribute
1088/// }
1089/// }
1090/// ```
1091///
1092/// The macro accepts a key-to-variable mapping in the format `key => variable_name: Type`.
1093/// The variable will be available as an `Option<Type>` in the function scope.
1094#[proc_macro_attribute]
1095pub fn attribute(attr: TokenStream, item: TokenStream) -> TokenStream {
1096 attribute_macro(attr, item)
1097}
1098
1099/// Extracts all attributes into a HashMap variable.
1100///
1101/// This attribute macro retrieves all available attributes from the request context
1102/// and makes them available as a HashMap for comprehensive attribute access.
1103///
1104/// # Usage
1105///
1106/// ```rust
1107/// use hyperlane_macros::*;
1108/// use hyperlane::*;
1109///
1110/// #[attributes(all_attrs)]
1111/// async fn handle_with_all_attributes(ctx: Context) {
1112/// for (key, value) in all_attrs {
1113/// // Process each attribute
1114/// }
1115/// }
1116/// ```
1117///
1118/// The macro accepts a variable name that will contain a HashMap of all attributes.
1119/// The variable will be available as a HashMap in the function scope.
1120#[proc_macro_attribute]
1121pub fn attributes(attr: TokenStream, item: TokenStream) -> TokenStream {
1122 attributes_macro(attr, item)
1123}
1124
1125/// Extracts a specific route parameter into a variable.
1126///
1127/// This attribute macro retrieves a specific route parameter by key and makes it
1128/// available as a variable. Route parameters are extracted from the URL path segments.
1129///
1130/// # Usage
1131///
1132/// ```rust
1133/// use hyperlane_macros::*;
1134/// use hyperlane::*;
1135///
1136/// // For route like "/users/{id}"
1137/// #[route_param("id" => user_id)]
1138/// async fn get_user(ctx: Context) {
1139/// if let Some(id) = user_id {
1140/// // Use the route parameter
1141/// }
1142/// }
1143/// ```
1144///
1145/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
1146/// The variable will be available as an `Option<String>` in the function scope.
1147#[proc_macro_attribute]
1148pub fn route_param(attr: TokenStream, item: TokenStream) -> TokenStream {
1149 route_param_macro(attr, item)
1150}
1151
1152/// Extracts all route parameters into a collection variable.
1153///
1154/// This attribute macro retrieves all available route parameters from the URL path
1155/// and makes them available as a collection for comprehensive route parameter access.
1156///
1157/// # Usage
1158///
1159/// ```rust
1160/// use hyperlane_macros::*;
1161/// use hyperlane::*;
1162///
1163/// // For route like "/users/{id}/posts/{post_id}"
1164/// #[route_params(params)]
1165/// async fn handle_nested_route(ctx: Context) {
1166/// for (key, value) in params {
1167/// // Process each route parameter
1168/// }
1169/// }
1170/// ```
1171///
1172/// The macro accepts a variable name that will contain all route parameters.
1173/// The variable will be available as a collection in the function scope.
1174#[proc_macro_attribute]
1175pub fn route_params(attr: TokenStream, item: TokenStream) -> TokenStream {
1176 route_params_macro(attr, item)
1177}
1178
1179/// Extracts a specific request query parameter into a variable.
1180///
1181/// This attribute macro retrieves a specific request query parameter by key and makes it
1182/// available as a variable. Query parameters are extracted from the URL request query string.
1183///
1184/// # Usage
1185///
1186/// ```rust
1187/// use hyperlane_macros::*;
1188/// use hyperlane::*;
1189///
1190/// // For URL like "/search?q=rust&limit=10"
1191/// #[request_query("q" => search_term)]
1192/// async fn search(ctx: Context) {
1193/// if let Some(term) = search_term {
1194/// // Use the request query parameter
1195/// }
1196/// }
1197/// ```
1198///
1199/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
1200/// The variable will be available as an `Option<String>` in the function scope.
1201#[proc_macro_attribute]
1202pub fn request_query(attr: TokenStream, item: TokenStream) -> TokenStream {
1203 request_query_macro(attr, item)
1204}
1205
1206/// Extracts all request query parameters into a collection variable.
1207///
1208/// This attribute macro retrieves all available request query parameters from the URL request query string
1209/// and makes them available as a collection for comprehensive request query parameter access.
1210///
1211/// # Usage
1212///
1213/// ```rust
1214/// use hyperlane_macros::*;
1215/// use hyperlane::*;
1216///
1217/// // For URL like "/search?q=rust&limit=10&sort=date"
1218/// #[request_querys(all_params)]
1219/// async fn search_with_params(ctx: Context) {
1220/// for (key, value) in all_params {
1221/// // Process each request query parameter
1222/// }
1223/// }
1224/// ```
1225///
1226/// The macro accepts a variable name that will contain all request query parameters.
1227/// The variable will be available as a collection in the function scope.
1228#[proc_macro_attribute]
1229pub fn request_querys(attr: TokenStream, item: TokenStream) -> TokenStream {
1230 request_querys_macro(attr, item)
1231}
1232
1233/// Extracts a specific HTTP request header into a variable.
1234///
1235/// This attribute macro retrieves a specific HTTP request header by name and makes it
1236/// available as a variable. Header values are extracted from the request request headers collection.
1237///
1238/// # Usage
1239///
1240/// ```rust
1241/// use hyperlane_macros::*;
1242/// use hyperlane::*;
1243///
1244/// #[request_header(HOST => host_request_header)]
1245/// async fn handle_with_host(ctx: Context) {
1246/// if let Some(host) = host_request_header {
1247/// // Use the host request_header value
1248/// }
1249/// }
1250///
1251/// #[request_header("Content-Type" => content_type)]
1252/// async fn handle_with_content_type(ctx: Context) {
1253/// if let Some(ct) = content_type {
1254/// // Use the content type request_header
1255/// }
1256/// }
1257/// ```
1258///
1259/// The macro accepts a request header name-to-variable mapping in the format `HEADER_NAME => variable_name`
1260/// or `"Header-Name" => variable_name`. The variable will be available as an `Option<String>`.
1261#[proc_macro_attribute]
1262pub fn request_header(attr: TokenStream, item: TokenStream) -> TokenStream {
1263 request_header_macro(attr, item)
1264}
1265
1266/// Extracts all HTTP request headers into a collection variable.
1267///
1268/// This attribute macro retrieves all available HTTP request headers from the request
1269/// and makes them available as a collection for comprehensive request header access.
1270///
1271/// # Usage
1272///
1273/// ```rust
1274/// use hyperlane_macros::*;
1275/// use hyperlane::*;
1276///
1277/// #[request_headers(all_request_headers)]
1278/// async fn handle_with_all_request_headers(ctx: Context) {
1279/// for (name, value) in all_request_headers {
1280/// // Process each request_header
1281/// }
1282/// }
1283/// ```
1284///
1285/// The macro accepts a variable name that will contain all HTTP request headers.
1286/// The variable will be available as a collection in the function scope.
1287#[proc_macro_attribute]
1288pub fn request_headers(attr: TokenStream, item: TokenStream) -> TokenStream {
1289 request_headers_macro(attr, item)
1290}
1291
1292/// Creates a new Server instance with the specified variable name.
1293///
1294/// This attribute macro generates a Server instance initialization at the beginning
1295/// of the function with the specified variable name.
1296///
1297/// # Usage
1298///
1299/// ```rust
1300/// use hyperlane_macros::*;
1301/// use hyperlane::*;
1302///
1303/// #[hyperlane(server)]
1304/// async fn handle_request(ctx: Context) {
1305/// // server is now available as: let server: Server = Server::new();
1306/// // Function body can use server
1307/// }
1308/// ```
1309///
1310/// The macro accepts a variable name as parameter. The variable will be available
1311/// as a Server instance in the function scope.
1312#[proc_macro_attribute]
1313pub fn hyperlane(attr: TokenStream, item: TokenStream) -> TokenStream {
1314 hyperlane_macro(attr, item)
1315}