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