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/// Extracts the raw request body into a specified variable.
1032///
1033/// This attribute macro extracts the raw request body content into a variable
1034/// with the fixed type `RequestBody`. The body content is not parsed or deserialized.
1035///
1036/// # Usage
1037///
1038/// ```rust
1039/// use hyperlane_macros::*;
1040/// use hyperlane::*;
1041///
1042/// #[request_body(raw_body)]
1043/// async fn handle_raw_body(ctx: Context) {
1044/// // Use the raw request body
1045/// let body_content = raw_body;
1046/// }
1047/// ```
1048///
1049/// The macro accepts only a variable name. The variable will be available
1050/// in the function scope as a `RequestBody` type.
1051#[proc_macro_attribute]
1052pub fn request_body(attr: TokenStream, item: TokenStream) -> TokenStream {
1053 request_body_macro(attr, item)
1054}
1055
1056/// Parses the request body as JSON into a specified variable and type.
1057///
1058/// This attribute macro extracts and deserializes the request body content as JSON into a variable
1059/// with the specified type. The body content is parsed as JSON using serde.
1060///
1061/// # Usage
1062///
1063/// ```rust
1064/// use hyperlane_macros::*;
1065/// use hyperlane::*;
1066/// use serde::Deserialize;
1067///
1068/// #[derive(Deserialize, Clone)]
1069/// struct UserData {
1070/// name: String,
1071/// age: u32,
1072/// }
1073///
1074/// #[request_body_json(user_data: UserData)]
1075/// async fn handle_user(ctx: Context) {
1076/// if let Ok(data) = user_data {
1077/// // Use the parsed user data
1078/// }
1079/// }
1080/// ```
1081///
1082/// The macro accepts a variable name and type in the format `variable_name: Type`.
1083/// The variable will be available in the function scope as a `Result<Type, JsonError>`.
1084#[proc_macro_attribute]
1085pub fn request_body_json(attr: TokenStream, item: TokenStream) -> TokenStream {
1086 request_body_json_macro(attr, item)
1087}
1088
1089/// Extracts a specific attribute value into a variable.
1090///
1091/// This attribute macro retrieves a specific attribute by key and makes it available
1092/// as a typed variable from the request context.
1093///
1094/// # Usage
1095///
1096/// ```rust
1097/// use hyperlane_macros::*;
1098/// use hyperlane::*;
1099/// use serde::Deserialize;
1100///
1101/// const USER_KEY: &str = "user_data";
1102///
1103/// #[derive(Deserialize, Clone)]
1104/// struct User {
1105/// id: u64,
1106/// name: String,
1107/// }
1108///
1109/// #[attribute(USER_KEY => user: User)]
1110/// async fn handle_with_attribute(ctx: Context) {
1111/// if let Some(user_data) = user {
1112/// // Use the extracted attribute
1113/// }
1114/// }
1115/// ```
1116///
1117/// The macro accepts a key-to-variable mapping in the format `key => variable_name: Type`.
1118/// The variable will be available as an `Option<Type>` in the function scope.
1119#[proc_macro_attribute]
1120pub fn attribute(attr: TokenStream, item: TokenStream) -> TokenStream {
1121 attribute_macro(attr, item)
1122}
1123
1124/// Extracts all attributes into a HashMap variable.
1125///
1126/// This attribute macro retrieves all available attributes from the request context
1127/// and makes them available as a HashMap for comprehensive attribute access.
1128///
1129/// # Usage
1130///
1131/// ```rust
1132/// use hyperlane_macros::*;
1133/// use hyperlane::*;
1134///
1135/// #[attributes(all_attrs)]
1136/// async fn handle_with_all_attributes(ctx: Context) {
1137/// for (key, value) in all_attrs {
1138/// // Process each attribute
1139/// }
1140/// }
1141/// ```
1142///
1143/// The macro accepts a variable name that will contain a HashMap of all attributes.
1144/// The variable will be available as a HashMap in the function scope.
1145#[proc_macro_attribute]
1146pub fn attributes(attr: TokenStream, item: TokenStream) -> TokenStream {
1147 attributes_macro(attr, item)
1148}
1149
1150/// Extracts a specific route parameter into a variable.
1151///
1152/// This attribute macro retrieves a specific route parameter by key and makes it
1153/// available as a variable. Route parameters are extracted from the URL path segments.
1154///
1155/// # Usage
1156///
1157/// ```rust
1158/// use hyperlane_macros::*;
1159/// use hyperlane::*;
1160///
1161/// // For route like "/users/{id}"
1162/// #[route_param("id" => user_id)]
1163/// async fn get_user(ctx: Context) {
1164/// if let Some(id) = user_id {
1165/// // Use the route parameter
1166/// }
1167/// }
1168/// ```
1169///
1170/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
1171/// The variable will be available as an `Option<String>` in the function scope.
1172#[proc_macro_attribute]
1173pub fn route_param(attr: TokenStream, item: TokenStream) -> TokenStream {
1174 route_param_macro(attr, item)
1175}
1176
1177/// Extracts all route parameters into a collection variable.
1178///
1179/// This attribute macro retrieves all available route parameters from the URL path
1180/// and makes them available as a collection for comprehensive route parameter access.
1181///
1182/// # Usage
1183///
1184/// ```rust
1185/// use hyperlane_macros::*;
1186/// use hyperlane::*;
1187///
1188/// // For route like "/users/{id}/posts/{post_id}"
1189/// #[route_params(params)]
1190/// async fn handle_nested_route(ctx: Context) {
1191/// for (key, value) in params {
1192/// // Process each route parameter
1193/// }
1194/// }
1195/// ```
1196///
1197/// The macro accepts a variable name that will contain all route parameters.
1198/// The variable will be available as a collection in the function scope.
1199#[proc_macro_attribute]
1200pub fn route_params(attr: TokenStream, item: TokenStream) -> TokenStream {
1201 route_params_macro(attr, item)
1202}
1203
1204/// Extracts a specific request query parameter into a variable.
1205///
1206/// This attribute macro retrieves a specific request query parameter by key and makes it
1207/// available as a variable. Query parameters are extracted from the URL request query string.
1208///
1209/// # Usage
1210///
1211/// ```rust
1212/// use hyperlane_macros::*;
1213/// use hyperlane::*;
1214///
1215/// // For URL like "/search?q=rust&limit=10"
1216/// #[request_query("q" => search_term)]
1217/// async fn search(ctx: Context) {
1218/// if let Some(term) = search_term {
1219/// // Use the request query parameter
1220/// }
1221/// }
1222/// ```
1223///
1224/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
1225/// The variable will be available as an `Option<String>` in the function scope.
1226#[proc_macro_attribute]
1227pub fn request_query(attr: TokenStream, item: TokenStream) -> TokenStream {
1228 request_query_macro(attr, item)
1229}
1230
1231/// Extracts all request query parameters into a collection variable.
1232///
1233/// This attribute macro retrieves all available request query parameters from the URL request query string
1234/// and makes them available as a collection for comprehensive request query parameter access.
1235///
1236/// # Usage
1237///
1238/// ```rust
1239/// use hyperlane_macros::*;
1240/// use hyperlane::*;
1241///
1242/// // For URL like "/search?q=rust&limit=10&sort=date"
1243/// #[request_querys(all_params)]
1244/// async fn search_with_params(ctx: Context) {
1245/// for (key, value) in all_params {
1246/// // Process each request query parameter
1247/// }
1248/// }
1249/// ```
1250///
1251/// The macro accepts a variable name that will contain all request query parameters.
1252/// The variable will be available as a collection in the function scope.
1253#[proc_macro_attribute]
1254pub fn request_querys(attr: TokenStream, item: TokenStream) -> TokenStream {
1255 request_querys_macro(attr, item)
1256}
1257
1258/// Extracts a specific HTTP request header into a variable.
1259///
1260/// This attribute macro retrieves a specific HTTP request header by name and makes it
1261/// available as a variable. Header values are extracted from the request request headers collection.
1262///
1263/// # Usage
1264///
1265/// ```rust
1266/// use hyperlane_macros::*;
1267/// use hyperlane::*;
1268///
1269/// #[request_header(HOST => host_request_header)]
1270/// async fn handle_with_host(ctx: Context) {
1271/// if let Some(host) = host_request_header {
1272/// // Use the host request_header value
1273/// }
1274/// }
1275///
1276/// #[request_header("Content-Type" => content_type)]
1277/// async fn handle_with_content_type(ctx: Context) {
1278/// if let Some(ct) = content_type {
1279/// // Use the content type request_header
1280/// }
1281/// }
1282/// ```
1283///
1284/// The macro accepts a request header name-to-variable mapping in the format `HEADER_NAME => variable_name`
1285/// or `"Header-Name" => variable_name`. The variable will be available as an `Option<String>`.
1286#[proc_macro_attribute]
1287pub fn request_header(attr: TokenStream, item: TokenStream) -> TokenStream {
1288 request_header_macro(attr, item)
1289}
1290
1291/// Extracts all HTTP request headers into a collection variable.
1292///
1293/// This attribute macro retrieves all available HTTP request headers from the request
1294/// and makes them available as a collection for comprehensive request header access.
1295///
1296/// # Usage
1297///
1298/// ```rust
1299/// use hyperlane_macros::*;
1300/// use hyperlane::*;
1301///
1302/// #[request_headers(all_request_headers)]
1303/// async fn handle_with_all_request_headers(ctx: Context) {
1304/// for (name, value) in all_request_headers {
1305/// // Process each request_header
1306/// }
1307/// }
1308/// ```
1309///
1310/// The macro accepts a variable name that will contain all HTTP request headers.
1311/// The variable will be available as a collection in the function scope.
1312#[proc_macro_attribute]
1313pub fn request_headers(attr: TokenStream, item: TokenStream) -> TokenStream {
1314 request_headers_macro(attr, item)
1315}
1316
1317/// Creates a new Server instance with the specified variable name.
1318///
1319/// This attribute macro generates a Server instance initialization at the beginning
1320/// of the function with the specified variable name.
1321///
1322/// # Usage
1323///
1324/// ```rust
1325/// use hyperlane_macros::*;
1326/// use hyperlane::*;
1327///
1328/// #[hyperlane(server)]
1329/// async fn handle_request(ctx: Context) {
1330/// // server is now available as: let server: Server = Server::new();
1331/// // Function body can use server
1332/// }
1333/// ```
1334///
1335/// The macro accepts a variable name as parameter. The variable will be available
1336/// as a Server instance in the function scope.
1337#[proc_macro_attribute]
1338pub fn hyperlane(attr: TokenStream, item: TokenStream) -> TokenStream {
1339 hyperlane_macro(attr, item)
1340}