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