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