hyperlane_macros/
lib.rs

1//! hyperlane-macros
2//!
3//! A comprehensive collection of procedural macros for building
4//! HTTP servers with enhanced functionality. This crate provides
5//! attribute macros that simplify HTTP request handling, protocol
6//! validation, response management, and request data extraction.
7
8mod aborted;
9mod closed;
10mod common;
11mod filter;
12mod flush;
13mod from_stream;
14mod hook;
15mod host;
16mod http;
17mod hyperlane;
18mod inject;
19mod protocol;
20mod referer;
21mod reject;
22mod request;
23mod request_middleware;
24mod response;
25mod response_middleware;
26mod route;
27mod send;
28mod stream;
29
30pub(crate) use aborted::*;
31pub(crate) use closed::*;
32pub(crate) use common::*;
33pub(crate) use filter::*;
34pub(crate) use flush::*;
35pub(crate) use from_stream::*;
36pub(crate) use hook::*;
37pub(crate) use host::*;
38pub(crate) use http::*;
39pub(crate) use hyperlane::*;
40pub(crate) use inject::*;
41pub(crate) use protocol::*;
42pub(crate) use referer::*;
43pub(crate) use reject::*;
44pub(crate) use request::*;
45pub(crate) use request_middleware::*;
46pub(crate) use response::*;
47pub(crate) use response_middleware::*;
48pub(crate) use route::*;
49pub(crate) use send::*;
50pub(crate) use stream::*;
51
52pub(crate) use proc_macro::TokenStream;
53pub(crate) use proc_macro2::TokenStream as TokenStream2;
54pub(crate) use quote::quote;
55pub(crate) use syn::{
56    Ident, Token,
57    parse::{Parse, ParseStream, Parser, Result},
58    punctuated::Punctuated,
59    token::Comma,
60    *,
61};
62
63inventory::collect!(InjectableMacro);
64
65/// Restricts function execution to HTTP GET requests only.
66///
67/// This attribute macro ensures the decorated function only executes when the incoming request
68/// uses the GET HTTP method. Requests with other methods will be filtered out.
69///
70/// # Usage
71///
72/// ```rust
73/// use hyperlane::*;
74/// use hyperlane_macros::*;
75///
76/// #[route("/get")]
77/// struct Get;
78///
79/// impl ServerHook for Get {
80///     async fn new(_ctx: &Context) -> Self {
81///         Self
82///     }
83///
84///     #[prologue_macros(get, response_body("get"))]
85///     async fn handle(self, ctx: &Context) {}
86/// }
87///
88/// impl Get {
89///     #[get]
90///     async fn get_with_ref_self(&self, ctx: &Context) {}
91/// }
92///
93/// #[get]
94/// async fn standalone_get_handler(ctx: &Context) {}
95/// ```
96///
97/// The macro takes no parameters and should be applied directly to async functions
98/// that accept a `&Context` parameter.
99#[proc_macro_attribute]
100pub fn get(_attr: TokenStream, item: TokenStream) -> TokenStream {
101    get_handler(item, Position::Prologue)
102}
103
104/// Restricts function execution to HTTP POST requests only.
105///
106/// This attribute macro ensures the decorated function only executes when the incoming request
107/// uses the POST HTTP method. Requests with other methods will be filtered out.
108///
109/// # Usage
110///
111/// ```rust
112/// use hyperlane::*;
113/// use hyperlane_macros::*;
114///
115/// #[route("/post")]
116/// struct Post;
117///
118/// impl ServerHook for Post {
119///     async fn new(_ctx: &Context) -> Self {
120///         Self
121///     }
122///
123///     #[prologue_macros(post, response_body("post"))]
124///     async fn handle(self, ctx: &Context) {}
125/// }
126///
127/// impl Post {
128///     #[post]
129///     async fn post_with_ref_self(&self, ctx: &Context) {}
130/// }
131///
132/// #[post]
133/// async fn standalone_post_handler(ctx: &Context) {}
134/// ```
135///
136/// The macro takes no parameters and should be applied directly to async functions
137/// that accept a `&Context` parameter.
138#[proc_macro_attribute]
139pub fn post(_attr: TokenStream, item: TokenStream) -> TokenStream {
140    epilogue_handler(item, Position::Prologue)
141}
142
143/// Restricts function execution to HTTP PUT requests only.
144///
145/// This attribute macro ensures the decorated function only executes when the incoming request
146/// uses the PUT HTTP method. Requests with other methods will be filtered out.
147///
148/// # Usage
149///
150/// ```rust
151/// use hyperlane::*;
152/// use hyperlane_macros::*;
153///
154/// #[route("/put")]
155/// struct Put;
156///
157/// impl ServerHook for Put {
158///     async fn new(_ctx: &Context) -> Self {
159///         Self
160///     }
161///
162///     #[prologue_macros(put, response_body("put"))]
163///     async fn handle(self, ctx: &Context) {}
164/// }
165///
166/// impl Put {
167///     #[put]
168///     async fn put_with_ref_self(&self, ctx: &Context) {}
169/// }
170///
171/// #[put]
172/// async fn standalone_put_handler(ctx: &Context) {}
173/// ```
174///
175/// The macro takes no parameters and should be applied directly to async functions
176/// that accept a `&Context` parameter.
177#[proc_macro_attribute]
178pub fn put(_attr: TokenStream, item: TokenStream) -> TokenStream {
179    put_handler(item, Position::Prologue)
180}
181
182/// Restricts function execution to HTTP DELETE requests only.
183///
184/// This attribute macro ensures the decorated function only executes when the incoming request
185/// uses the DELETE HTTP method. Requests with other methods will be filtered out.
186///
187/// # Usage
188///
189/// ```rust
190/// use hyperlane::*;
191/// use hyperlane_macros::*;
192///
193/// #[route("/delete")]
194/// struct Delete;
195///
196/// impl ServerHook for Delete {
197///     async fn new(_ctx: &Context) -> Self {
198///         Self
199///     }
200///
201///     #[prologue_macros(delete, response_body("delete"))]
202///     async fn handle(self, ctx: &Context) {}
203/// }
204///
205/// impl Delete {
206///     #[delete]
207///     async fn delete_with_ref_self(&self, ctx: &Context) {}
208/// }
209///
210/// #[delete]
211/// async fn standalone_delete_handler(ctx: &Context) {}
212/// ```
213///
214/// The macro takes no parameters and should be applied directly to async functions
215/// that accept a `&Context` parameter.
216#[proc_macro_attribute]
217pub fn delete(_attr: TokenStream, item: TokenStream) -> TokenStream {
218    delete_handler(item, Position::Prologue)
219}
220
221/// Restricts function execution to HTTP PATCH requests only.
222///
223/// This attribute macro ensures the decorated function only executes when the incoming request
224/// uses the PATCH HTTP method. Requests with other methods will be filtered out.
225///
226/// # Usage
227///
228/// ```rust
229/// use hyperlane::*;
230/// use hyperlane_macros::*;
231///
232/// #[route("/patch")]
233/// struct Patch;
234///
235/// impl ServerHook for Patch {
236///     async fn new(_ctx: &Context) -> Self {
237///         Self
238///     }
239///
240///     #[prologue_macros(patch, response_body("patch"))]
241///     async fn handle(self, ctx: &Context) {}
242/// }
243///
244/// impl Patch {
245///     #[patch]
246///     async fn patch_with_ref_self(&self, ctx: &Context) {}
247/// }
248///
249/// #[patch]
250/// async fn standalone_patch_handler(ctx: &Context) {}
251/// ```
252///
253/// The macro takes no parameters and should be applied directly to async functions
254/// that accept a `&Context` parameter.
255#[proc_macro_attribute]
256pub fn patch(_attr: TokenStream, item: TokenStream) -> TokenStream {
257    patch_handler(item, Position::Prologue)
258}
259
260/// Restricts function execution to HTTP HEAD requests only.
261///
262/// This attribute macro ensures the decorated function only executes when the incoming request
263/// uses the HEAD HTTP method. Requests with other methods will be filtered out.
264///
265/// # Usage
266///
267/// ```rust
268/// use hyperlane::*;
269/// use hyperlane_macros::*;
270///
271/// #[route("/head")]
272/// struct Head;
273///
274/// impl ServerHook for Head {
275///     async fn new(_ctx: &Context) -> Self {
276///         Self
277///     }
278///
279///     #[prologue_macros(head, response_body("head"))]
280///     async fn handle(self, ctx: &Context) {}
281/// }
282///
283/// impl Head {
284///     #[head]
285///     async fn head_with_ref_self(&self, ctx: &Context) {}
286/// }
287///
288/// #[head]
289/// async fn standalone_head_handler(ctx: &Context) {}
290/// ```
291///
292/// The macro takes no parameters and should be applied directly to async functions
293/// that accept a `&Context` parameter.
294#[proc_macro_attribute]
295pub fn head(_attr: TokenStream, item: TokenStream) -> TokenStream {
296    head_handler(item, Position::Prologue)
297}
298
299/// Restricts function execution to HTTP OPTIONS requests only.
300///
301/// This attribute macro ensures the decorated function only executes when the incoming request
302/// uses the OPTIONS HTTP method. Requests with other methods will be filtered out.
303///
304/// # Usage
305///
306/// ```rust
307/// use hyperlane::*;
308/// use hyperlane_macros::*;
309///
310/// #[route("/options")]
311/// struct Options;
312///
313/// impl ServerHook for Options {
314///     async fn new(_ctx: &Context) -> Self {
315///         Self
316///     }
317///
318///     #[prologue_macros(options, response_body("options"))]
319///     async fn handle(self, ctx: &Context) {}
320/// }
321///
322/// impl Options {
323///     #[options]
324///     async fn options_with_ref_self(&self, ctx: &Context) {}
325/// }
326///
327/// #[options]
328/// async fn standalone_options_handler(ctx: &Context) {}
329/// ```
330///
331/// The macro takes no parameters and should be applied directly to async functions
332/// that accept a `&Context` parameter.
333#[proc_macro_attribute]
334pub fn options(_attr: TokenStream, item: TokenStream) -> TokenStream {
335    options_handler(item, Position::Prologue)
336}
337
338/// Restricts function execution to HTTP CONNECT requests only.
339///
340/// This attribute macro ensures the decorated function only executes when the incoming request
341/// uses the CONNECT HTTP method. Requests with other methods will be filtered out.
342///
343/// # Usage
344///
345/// ```rust
346/// use hyperlane::*;
347/// use hyperlane_macros::*;
348///
349/// #[route("/connect")]
350/// struct Connect;
351///
352/// impl ServerHook for Connect {
353///     async fn new(_ctx: &Context) -> Self {
354///         Self
355///     }
356///
357///     #[prologue_macros(connect, response_body("connect"))]
358///     async fn handle(self, ctx: &Context) {}
359/// }
360///
361/// impl Connect {
362///     #[connect]
363///     async fn connect_with_ref_self(&self, ctx: &Context) {}
364/// }
365///
366/// #[connect]
367/// async fn standalone_connect_handler(ctx: &Context) {}
368/// ```
369///
370/// The macro takes no parameters and should be applied directly to async functions
371/// that accept a `&Context` parameter.
372#[proc_macro_attribute]
373pub fn connect(_attr: TokenStream, item: TokenStream) -> TokenStream {
374    connect_handler(item, Position::Prologue)
375}
376
377/// Restricts function execution to HTTP TRACE requests only.
378///
379/// This attribute macro ensures the decorated function only executes when the incoming request
380/// uses the TRACE HTTP method. Requests with other methods will be filtered out.
381///
382/// # Usage
383///
384/// ```rust
385/// use hyperlane::*;
386/// use hyperlane_macros::*;
387///
388/// #[route("/trace")]
389/// struct Trace;
390///
391/// impl ServerHook for Trace {
392///     async fn new(_ctx: &Context) -> Self {
393///         Self
394///     }
395///
396///     #[prologue_macros(trace, response_body("trace"))]
397///     async fn handle(self, ctx: &Context) {}
398/// }
399///
400/// impl Trace {
401///     #[trace]
402///     async fn trace_with_ref_self(&self, ctx: &Context) {}
403/// }
404///
405/// #[trace]
406/// async fn standalone_trace_handler(ctx: &Context) {}
407/// ```
408///
409/// The macro takes no parameters and should be applied directly to async functions
410/// that accept a `&Context` parameter.
411#[proc_macro_attribute]
412pub fn trace(_attr: TokenStream, item: TokenStream) -> TokenStream {
413    trace_handler(item, Position::Prologue)
414}
415
416/// Allows function to handle multiple HTTP methods.
417///
418/// This attribute macro configures the decorated function to execute for any of the specified
419/// HTTP methods. Methods should be provided as a comma-separated list.
420///
421/// # Usage
422///
423/// ```rust
424/// use hyperlane::*;
425/// use hyperlane_macros::*;
426///
427/// #[route("/get_post")]
428/// struct GetPost;
429///
430/// impl ServerHook for GetPost {
431///     async fn new(_ctx: &Context) -> Self {
432///         Self
433///     }
434///
435///     #[prologue_macros(
436///         http,
437///         methods(get, post),
438///         response_body("get_post")
439///     )]
440///     async fn handle(self, ctx: &Context) {}
441/// }
442///
443/// impl GetPost {
444///     #[methods(get, post)]
445///     async fn methods_with_ref_self(&self, ctx: &Context) {}
446/// }
447///
448/// #[methods(get, post)]
449/// async fn standalone_methods_handler(ctx: &Context) {}
450/// ```
451///
452/// The macro accepts a comma-separated list of HTTP method names (lowercase) and should be
453/// applied to async functions that accept a `&Context` parameter.
454#[proc_macro_attribute]
455pub fn methods(attr: TokenStream, item: TokenStream) -> TokenStream {
456    methods_macro(attr, item, Position::Prologue)
457}
458
459/// Restricts function execution to WebSocket upgrade requests only.
460///
461/// This attribute macro ensures the decorated function only executes when the incoming request
462/// is a valid WebSocket upgrade request with proper request headers and protocol negotiation.
463///
464/// # Usage
465///
466/// ```rust
467/// use hyperlane::*;
468/// use hyperlane_macros::*;
469///
470/// #[route("/ws")]
471/// struct Websocket;
472///
473/// impl ServerHook for Websocket {
474///     async fn new(_ctx: &Context) -> Self {
475///         Self
476///     }
477///
478///     #[ws]
479///     #[ws_from_stream]
480///     async fn handle(self, ctx: &Context) {
481///         let body: RequestBody = ctx.get_request_body().await;
482///         let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
483///         ctx.send_body_list_with_data(&body_list).await.unwrap();
484///     }
485/// }
486///
487/// impl Websocket {
488///     #[ws]
489///     async fn ws_with_ref_self(&self, ctx: &Context) {}
490/// }
491///
492/// #[ws]
493/// async fn standalone_ws_handler(ctx: &Context) {}
494/// ```
495///
496/// The macro takes no parameters and should be applied directly to async functions
497/// that accept a `&Context` parameter.
498#[proc_macro_attribute]
499pub fn ws(_attr: TokenStream, item: TokenStream) -> TokenStream {
500    ws_macro(item, Position::Prologue)
501}
502
503/// Restricts function execution to standard HTTP requests only.
504///
505/// This attribute macro ensures the decorated function only executes for standard HTTP requests,
506/// excluding WebSocket upgrades and other protocol upgrade requests.
507///
508/// # Usage
509///
510/// ```rust
511/// use hyperlane::*;
512/// use hyperlane_macros::*;
513///
514/// #[route("/http")]
515/// struct HttpOnly;
516///
517/// impl ServerHook for HttpOnly {
518///     async fn new(_ctx: &Context) -> Self {
519///         Self
520///     }
521///
522///     #[prologue_macros(http, response_body("http"))]
523///     async fn handle(self, ctx: &Context) {}
524/// }
525///
526/// impl HttpOnly {
527///     #[http]
528///     async fn http_with_ref_self(&self, ctx: &Context) {}
529/// }
530///
531/// #[http]
532/// async fn standalone_http_handler(ctx: &Context) {}
533/// ```
534///
535/// The macro takes no parameters and should be applied directly to async functions
536/// that accept a `&Context` parameter.
537#[proc_macro_attribute]
538pub fn http(_attr: TokenStream, item: TokenStream) -> TokenStream {
539    http_macro(item, Position::Prologue)
540}
541
542/// Sets the HTTP status code for the response.
543///
544/// This attribute macro configures the HTTP status code that will be sent with the response.
545/// The status code can be provided as a numeric literal or a global constant.
546///
547/// # Usage
548///
549/// ```rust
550/// use hyperlane::*;
551/// use hyperlane_macros::*;
552///
553/// const CUSTOM_STATUS_CODE: i32 = 200;
554///
555/// #[route("/response")]
556/// struct Response;
557///
558/// impl ServerHook for Response {
559///     async fn new(_ctx: &Context) -> Self {
560///         Self
561///     }
562///
563///     #[response_status_code(CUSTOM_STATUS_CODE)]
564///     async fn handle(self, ctx: &Context) {}
565/// }
566///
567/// impl Response {
568///     #[response_status_code(CUSTOM_STATUS_CODE)]
569///     async fn response_status_code_with_ref_self(&self, ctx: &Context) {}
570/// }
571///
572/// #[response_status_code(200)]
573/// async fn standalone_response_status_code_handler(ctx: &Context) {}
574/// ```
575///
576/// The macro accepts a numeric HTTP status code or a global constant
577/// and should be applied to async functions that accept a `&Context` parameter.
578#[proc_macro_attribute]
579pub fn response_status_code(attr: TokenStream, item: TokenStream) -> TokenStream {
580    response_status_code_macro(attr, item, Position::Prologue)
581}
582
583/// Sets the HTTP reason phrase for the response.
584///
585/// This attribute macro configures the HTTP reason phrase that accompanies the status code.
586/// The reason phrase can be provided as a string literal or a global constant.
587///
588/// # Usage
589///
590/// ```rust
591/// use hyperlane::*;
592/// use hyperlane_macros::*;
593///
594/// const CUSTOM_REASON: &str = "Accepted";
595///
596/// #[route("/response")]
597/// struct Response;
598///
599/// impl ServerHook for Response {
600///     async fn new(_ctx: &Context) -> Self {
601///         Self
602///     }
603///
604///     #[response_reason_phrase(CUSTOM_REASON)]
605///     async fn handle(self, ctx: &Context) {}
606/// }
607///
608/// impl Response {
609///     #[response_reason_phrase(CUSTOM_REASON)]
610///     async fn response_reason_phrase_with_ref_self(&self, ctx: &Context) {}
611/// }
612///
613/// #[response_reason_phrase("OK")]
614/// async fn standalone_response_reason_phrase_handler(ctx: &Context) {}
615/// ```
616///
617/// The macro accepts a string literal or global constant for the reason phrase and should be
618/// applied to async functions that accept a `&Context` parameter.
619#[proc_macro_attribute]
620pub fn response_reason_phrase(attr: TokenStream, item: TokenStream) -> TokenStream {
621    response_reason_phrase_macro(attr, item, Position::Prologue)
622}
623
624/// Sets or replaces a specific HTTP response header.
625///
626/// This attribute macro configures a specific HTTP response header that will be sent with the response.
627/// Both the header name and value can be provided as string literals or global constants.
628/// Use `"key", "value"` to set a header (add to existing headers) or `"key" => "value"` to replace a header (overwrite existing).
629///
630/// # Usage
631///
632/// ```rust
633/// use hyperlane::*;
634/// use hyperlane_macros::*;
635///
636/// const CUSTOM_HEADER_NAME: &str = "X-Custom-Header";
637/// const CUSTOM_HEADER_VALUE: &str = "custom-value";
638///
639/// #[route("/response")]
640/// struct Response;
641///
642/// impl ServerHook for Response {
643///     async fn new(_ctx: &Context) -> Self {
644///         Self
645///     }
646///
647///     #[response_header(CUSTOM_HEADER_NAME => CUSTOM_HEADER_VALUE)]
648///     async fn handle(self, ctx: &Context) {}
649/// }
650///
651/// impl Response {
652///     #[response_header(CUSTOM_HEADER_NAME => CUSTOM_HEADER_VALUE)]
653///     async fn response_header_with_ref_self(&self, ctx: &Context) {}
654/// }
655///
656/// #[route("/response_header")]
657/// struct ResponseHeaderTest;
658///
659/// impl ServerHook for ResponseHeaderTest {
660///     async fn new(_ctx: &Context) -> Self {
661///         Self
662///     }
663///
664///     #[response_body("Testing header set and replace operations")]
665///     #[response_header("X-Add-Header", "add-value")]
666///     #[response_header("X-Set-Header" => "set-value")]
667///     async fn handle(self, ctx: &Context) {}
668/// }
669///
670/// #[response_header("X-Custom" => "value")]
671/// async fn standalone_response_header_handler(ctx: &Context) {}
672/// ```
673///
674/// The macro accepts header name and header value, both can be string literals or global constants.
675/// Use `"key", "value"` for setting headers and `"key" => "value"` for replacing headers.
676/// Should be applied to async functions that accept a `&Context` parameter.
677#[proc_macro_attribute]
678pub fn response_header(attr: TokenStream, item: TokenStream) -> TokenStream {
679    response_header_macro(attr, item, Position::Prologue)
680}
681
682/// Sets the HTTP response body.
683///
684/// This attribute macro configures the HTTP response body that will be sent with the response.
685/// The body content can be provided as a string literal or a global constant.
686///
687/// # Usage
688///
689/// ```rust
690/// use hyperlane::*;
691/// use hyperlane_macros::*;
692///
693/// const RESPONSE_DATA: &str = "{\"status\": \"success\"}";
694///
695/// #[route("/response")]
696/// struct Response;
697///
698/// impl ServerHook for Response {
699///     async fn new(_ctx: &Context) -> Self {
700///         Self
701///     }
702///
703///     #[response_body(&RESPONSE_DATA)]
704///     async fn handle(self, ctx: &Context) {}
705/// }
706///
707/// impl Response {
708///     #[response_body(&RESPONSE_DATA)]
709///     async fn response_body_with_ref_self(&self, ctx: &Context) {}
710/// }
711///
712/// #[response_body("standalone response body")]
713/// async fn standalone_response_body_handler(ctx: &Context) {}
714/// ```
715///
716/// The macro accepts a string literal or global constant for the response body and should be
717/// applied to async functions that accept a `&Context` parameter.
718#[proc_macro_attribute]
719pub fn response_body(attr: TokenStream, item: TokenStream) -> TokenStream {
720    response_body_macro(attr, item, Position::Prologue)
721}
722
723/// Clears all response headers.
724///
725/// This attribute macro clears all response headers from the response.
726///
727/// # Usage
728///
729/// ```rust
730/// use hyperlane::*;
731/// use hyperlane_macros::*;
732///
733/// #[route("/unknown_method")]
734/// struct UnknownMethod;
735///
736/// impl ServerHook for UnknownMethod {
737///     async fn new(_ctx: &Context) -> Self {
738///         Self
739///     }
740///
741///     #[prologue_macros(
742///         clear_response_headers,
743///         filter(ctx.get_request().await.is_unknown_method()),
744///         response_body("unknown_method")
745///     )]
746///     async fn handle(self, ctx: &Context) {}
747/// }
748///
749/// impl UnknownMethod {
750///     #[clear_response_headers]
751///     async fn clear_response_headers_with_ref_self(&self, ctx: &Context) {}
752/// }
753///
754/// #[clear_response_headers]
755/// async fn standalone_clear_response_headers_handler(ctx: &Context) {}
756/// ```
757///
758/// The macro should be applied to async functions that accept a `&Context` parameter.   
759#[proc_macro_attribute]
760pub fn clear_response_headers(_attr: TokenStream, item: TokenStream) -> TokenStream {
761    clear_response_headers_macro(item, Position::Prologue)
762}
763
764/// Sets the HTTP response version.
765///
766/// This attribute macro configures the HTTP response version that will be sent with the response.
767/// The version can be provided as a variable or code block.
768///
769/// # Usage
770///
771/// ```rust
772/// use hyperlane::*;
773/// use hyperlane_macros::*;
774///
775/// #[request_middleware]
776/// struct RequestMiddleware;
777///
778/// impl ServerHook for RequestMiddleware {
779///     async fn new(_ctx: &Context) -> Self {
780///         Self
781///     }
782///
783///     #[epilogue_macros(
784///         response_status_code(200),
785///         response_version(HttpVersion::HTTP1_1),
786///         response_header(SERVER => HYPERLANE)
787///     )]
788///     async fn handle(self, ctx: &Context) {}
789/// }
790/// ```
791///
792/// The macro accepts a variable or code block for the response version and should be
793/// applied to async functions that accept a `&Context` parameter.
794#[proc_macro_attribute]
795pub fn response_version(attr: TokenStream, item: TokenStream) -> TokenStream {
796    response_version_macro(attr, item, Position::Prologue)
797}
798
799/// Automatically sends the complete response after function execution.
800///
801/// This attribute macro ensures that the response (request headers and body) is automatically sent
802/// to the client after the function completes execution.
803///
804/// # Usage
805///
806/// ```rust
807/// use hyperlane::*;
808/// use hyperlane_macros::*;
809///
810/// #[route("/send")]
811/// struct SendTest;
812///
813/// impl ServerHook for SendTest {
814///     async fn new(_ctx: &Context) -> Self {
815///         Self
816///     }
817///
818///     #[epilogue_macros(send)]
819///     async fn handle(self, ctx: &Context) {}
820/// }
821///
822/// impl SendTest {
823///     #[send]
824///     async fn send_with_ref_self(&self, ctx: &Context) {}
825/// }
826///
827/// #[send]
828/// async fn standalone_send_handler(ctx: &Context) {}
829/// ```
830///
831/// The macro takes no parameters and should be applied directly to async functions
832/// that accept a `&Context` parameter.
833#[proc_macro_attribute]
834pub fn send(_attr: TokenStream, item: TokenStream) -> TokenStream {
835    send_macro(item, Position::Epilogue)
836}
837
838/// Automatically sends only the response body after function execution.
839///
840/// This attribute macro ensures that only the response body is automatically sent
841/// to the client after the function completes, handling request headers separately.
842///
843/// # Usage
844///
845/// ```rust
846/// use hyperlane::*;
847/// use hyperlane_macros::*;
848///
849/// #[route("/send_body")]
850/// struct SendBodyTest;
851///
852/// impl ServerHook for SendBodyTest {
853///     async fn new(_ctx: &Context) -> Self {
854///         Self
855///     }
856///
857///     #[epilogue_macros(send_body)]
858///     async fn handle(self, ctx: &Context) {}
859/// }
860///
861/// impl SendBodyTest {
862///     #[send_body]
863///     async fn send_body_with_ref_self(&self, ctx: &Context) {}
864/// }
865///
866/// #[send_body]
867/// async fn standalone_send_body_handler(ctx: &Context) {}
868/// ```
869///
870/// The macro takes no parameters and should be applied directly to async functions
871/// that accept a `&Context` parameter.
872#[proc_macro_attribute]
873pub fn send_body(_attr: TokenStream, item: TokenStream) -> TokenStream {
874    send_body_macro(item, Position::Epilogue)
875}
876
877/// Flushes the response stream after function execution.
878///
879/// This attribute macro ensures that the response stream is flushed to guarantee immediate
880/// data transmission, forcing any buffered response data to be sent to the client.
881///
882/// # Usage
883///
884/// ```rust
885/// use hyperlane::*;
886/// use hyperlane_macros::*;
887///
888/// #[route("/flush")]
889/// struct FlushTest;
890///
891/// impl ServerHook for FlushTest {
892///     async fn new(_ctx: &Context) -> Self {
893///         Self
894///     }
895///
896///     #[epilogue_macros(flush)]
897///     async fn handle(self, ctx: &Context) {}
898/// }
899///
900/// impl FlushTest {
901///     #[flush]
902///     async fn flush_with_ref_self(&self, ctx: &Context) {}
903/// }
904///
905/// #[flush]
906/// async fn standalone_flush_handler(ctx: &Context) {}
907/// ```
908///
909/// The macro takes no parameters and should be applied directly to async functions
910/// that accept a `&Context` parameter.
911#[proc_macro_attribute]
912pub fn flush(_attr: TokenStream, item: TokenStream) -> TokenStream {
913    flush_macro(item, Position::Prologue)
914}
915
916/// Handles aborted request scenarios.
917///
918/// This attribute macro configures the function to handle cases where the client has
919/// aborted the request, providing appropriate handling for interrupted or cancelled requests.
920///
921/// # Usage
922///
923/// ```rust
924/// use hyperlane::*;
925/// use hyperlane_macros::*;
926///
927/// #[route("/aborted")]
928/// struct Aborted;
929///
930/// impl ServerHook for Aborted {
931///     async fn new(_ctx: &Context) -> Self {
932///         Self
933///     }
934///
935///     #[aborted]
936///     async fn handle(self, ctx: &Context) {}
937/// }
938///
939/// impl Aborted {
940///     #[aborted]
941///     async fn aborted_with_ref_self(&self, ctx: &Context) {}
942/// }
943///
944/// #[aborted]
945/// async fn standalone_aborted_handler(ctx: &Context) {}
946/// ```
947///
948/// The macro takes no parameters and should be applied directly to async functions
949/// that accept a `&Context` parameter.
950#[proc_macro_attribute]
951pub fn aborted(_attr: TokenStream, item: TokenStream) -> TokenStream {
952    aborted_macro(item, Position::Prologue)
953}
954
955/// Handles closed connection scenarios.
956///
957/// This attribute macro configures the function to handle cases where the connection
958/// has been closed, providing appropriate handling for terminated or disconnected connections.
959///
960/// # Usage
961///
962/// ```rust
963/// use hyperlane::*;
964/// use hyperlane_macros::*;
965///
966/// #[route("/closed")]
967/// struct ClosedTest;
968///
969/// impl ServerHook for ClosedTest {
970///     async fn new(_ctx: &Context) -> Self {
971///         Self
972///     }
973///
974///     #[closed]
975///     async fn handle(self, ctx: &Context) {}
976/// }
977///
978/// impl ClosedTest {
979///     #[closed]
980///     async fn closed_with_ref_self(&self, ctx: &Context) {}
981/// }
982///
983/// #[closed]
984/// async fn standalone_closed_handler(ctx: &Context) {}
985/// ```
986///
987/// The macro takes no parameters and should be applied directly to async functions
988/// that accept a `&Context` parameter.
989#[proc_macro_attribute]
990pub fn closed(_attr: TokenStream, item: TokenStream) -> TokenStream {
991    closed_macro(item, Position::Prologue)
992}
993
994/// Restricts function execution to HTTP/2 Cleartext (h2c) requests only.
995///
996/// This attribute macro ensures the decorated function only executes for HTTP/2 cleartext
997/// requests that use the h2c upgrade mechanism.
998///
999/// # Usage
1000///
1001/// ```rust
1002/// use hyperlane::*;
1003/// use hyperlane_macros::*;
1004///
1005/// #[route("/h2c")]
1006/// struct H2c;
1007///
1008/// impl ServerHook for H2c {
1009///     async fn new(_ctx: &Context) -> Self {
1010///         Self
1011///     }
1012///
1013///     #[prologue_macros(h2c, response_body("h2c"))]
1014///     async fn handle(self, ctx: &Context) {}
1015/// }
1016///
1017/// impl H2c {
1018///     #[h2c]
1019///     async fn h2c_with_ref_self(&self, ctx: &Context) {}
1020/// }
1021///
1022/// #[h2c]
1023/// async fn standalone_h2c_handler(ctx: &Context) {}
1024/// ```
1025///
1026/// The macro takes no parameters and should be applied directly to async functions
1027/// that accept a `&Context` parameter.
1028#[proc_macro_attribute]
1029pub fn h2c(_attr: TokenStream, item: TokenStream) -> TokenStream {
1030    h2c_macro(item, Position::Prologue)
1031}
1032
1033/// Restricts function execution to HTTP/0.9 requests only.
1034///
1035/// This attribute macro ensures the decorated function only executes for HTTP/0.9
1036/// protocol requests, the earliest version of the HTTP protocol.
1037///
1038/// # Usage
1039///
1040/// ```rust
1041/// use hyperlane::*;
1042/// use hyperlane_macros::*;
1043///
1044/// #[route("/http0_9")]
1045/// struct Http09;
1046///
1047/// impl ServerHook for Http09 {
1048///     async fn new(_ctx: &Context) -> Self {
1049///         Self
1050///     }
1051///
1052///     #[prologue_macros(http0_9, response_body("http0_9"))]
1053///     async fn handle(self, ctx: &Context) {}
1054/// }
1055///
1056/// impl Http09 {
1057///     #[http0_9]
1058///     async fn http0_9_with_ref_self(&self, ctx: &Context) {}
1059/// }
1060///
1061/// #[http0_9]
1062/// async fn standalone_http0_9_handler(ctx: &Context) {}
1063/// ```
1064///
1065/// The macro takes no parameters and should be applied directly to async functions
1066/// that accept a `&Context` parameter.
1067#[proc_macro_attribute]
1068pub fn http0_9(_attr: TokenStream, item: TokenStream) -> TokenStream {
1069    http0_9_macro(item, Position::Prologue)
1070}
1071
1072/// Restricts function execution to HTTP/1.0 requests only.
1073///
1074/// This attribute macro ensures the decorated function only executes for HTTP/1.0
1075/// protocol requests.
1076///
1077/// # Usage
1078///
1079/// ```rust
1080/// use hyperlane::*;
1081/// use hyperlane_macros::*;
1082///
1083/// #[route("/http1_0")]
1084/// struct Http10;
1085///
1086/// impl ServerHook for Http10 {
1087///     async fn new(_ctx: &Context) -> Self {
1088///         Self
1089///     }
1090///
1091///     #[prologue_macros(http1_0, response_body("http1_0"))]
1092///     async fn handle(self, ctx: &Context) {}
1093/// }
1094///
1095/// impl Http10 {
1096///     #[http1_0]
1097///     async fn http1_0_with_ref_self(&self, ctx: &Context) {}
1098/// }
1099///
1100/// #[http1_0]
1101/// async fn standalone_http1_0_handler(ctx: &Context) {}
1102/// ```
1103///
1104/// The macro takes no parameters and should be applied directly to async functions
1105/// that accept a `&Context` parameter.
1106#[proc_macro_attribute]
1107pub fn http1_0(_attr: TokenStream, item: TokenStream) -> TokenStream {
1108    http1_0_macro(item, Position::Prologue)
1109}
1110
1111/// Restricts function execution to HTTP/1.1 requests only.
1112///
1113/// This attribute macro ensures the decorated function only executes for HTTP/1.1
1114/// protocol requests.
1115///
1116/// # Usage
1117///
1118/// ```rust
1119/// use hyperlane::*;
1120/// use hyperlane_macros::*;
1121///
1122/// #[route("/http1_1")]
1123/// struct Http11;
1124///
1125/// impl ServerHook for Http11 {
1126///     async fn new(_ctx: &Context) -> Self {
1127///         Self
1128///     }
1129///
1130///     #[prologue_macros(http1_1, response_body("http1_1"))]
1131///     async fn handle(self, ctx: &Context) {}
1132/// }
1133///
1134/// impl Http11 {
1135///     #[http1_1]
1136///     async fn http1_1_with_ref_self(&self, ctx: &Context) {}
1137/// }
1138///
1139/// #[http1_1]
1140/// async fn standalone_http1_1_handler(ctx: &Context) {}
1141/// ```
1142///
1143/// The macro takes no parameters and should be applied directly to async functions
1144/// that accept a `&Context` parameter.
1145#[proc_macro_attribute]
1146pub fn http1_1(_attr: TokenStream, item: TokenStream) -> TokenStream {
1147    http1_1_macro(item, Position::Prologue)
1148}
1149
1150/// Restricts function execution to HTTP/1.1 or higher protocol versions.
1151///
1152/// This attribute macro ensures the decorated function only executes for HTTP/1.1
1153/// or newer protocol versions, including HTTP/2, HTTP/3, and future versions.
1154///
1155/// # Usage
1156///
1157/// ```rust
1158/// use hyperlane::*;
1159/// use hyperlane_macros::*;
1160///
1161/// #[route("/http1_1_or_higher")]
1162/// struct Http11OrHigher;
1163///
1164/// impl ServerHook for Http11OrHigher {
1165///     async fn new(_ctx: &Context) -> Self {
1166///         Self
1167///     }
1168///
1169///     #[prologue_macros(http1_1_or_higher, response_body("http1_1_or_higher"))]
1170///     async fn handle(self, ctx: &Context) {}
1171/// }
1172///
1173/// impl Http11OrHigher {
1174///     #[http1_1_or_higher]
1175///     async fn http1_1_or_higher_with_ref_self(&self, ctx: &Context) {}
1176/// }
1177///
1178/// #[http1_1_or_higher]
1179/// async fn standalone_http1_1_or_higher_handler(ctx: &Context) {}
1180/// ```
1181///
1182/// The macro takes no parameters and should be applied directly to async functions
1183/// that accept a `&Context` parameter.
1184#[proc_macro_attribute]
1185pub fn http1_1_or_higher(_attr: TokenStream, item: TokenStream) -> TokenStream {
1186    http1_1_or_higher_macro(item, Position::Prologue)
1187}
1188
1189/// Restricts function execution to HTTP/2 requests only.
1190///
1191/// This attribute macro ensures the decorated function only executes for HTTP/2
1192/// protocol requests.
1193///
1194/// # Usage
1195///
1196/// ```rust
1197/// use hyperlane::*;
1198/// use hyperlane_macros::*;
1199///
1200/// #[route("/http2")]
1201/// struct Http2;
1202///
1203/// impl ServerHook for Http2 {
1204///     async fn new(_ctx: &Context) -> Self {
1205///         Self
1206///     }
1207///
1208///     #[prologue_macros(http2, response_body("http2"))]
1209///     async fn handle(self, ctx: &Context) {}
1210/// }
1211///
1212/// impl Http2 {
1213///     #[http2]
1214///     async fn http2_with_ref_self(&self, ctx: &Context) {}
1215/// }
1216///
1217/// #[http2]
1218/// async fn standalone_http2_handler(ctx: &Context) {}
1219/// ```
1220///
1221/// The macro takes no parameters and should be applied directly to async functions
1222/// that accept a `&Context` parameter.
1223#[proc_macro_attribute]
1224pub fn http2(_attr: TokenStream, item: TokenStream) -> TokenStream {
1225    http2_macro(item, Position::Prologue)
1226}
1227
1228/// Restricts function execution to HTTP/3 requests only.
1229///
1230/// This attribute macro ensures the decorated function only executes for HTTP/3
1231/// protocol requests, the latest version of the HTTP protocol.
1232///
1233/// # Usage
1234///
1235/// ```rust
1236/// use hyperlane::*;
1237/// use hyperlane_macros::*;
1238///
1239/// #[route("/http3")]
1240/// struct Http3;
1241///
1242/// impl ServerHook for Http3 {
1243///     async fn new(_ctx: &Context) -> Self {
1244///         Self
1245///     }
1246///
1247///     #[prologue_macros(http3, response_body("http3"))]
1248///     async fn handle(self, ctx: &Context) {}
1249/// }
1250///
1251/// impl Http3 {
1252///     #[http3]
1253///     async fn http3_with_ref_self(&self, ctx: &Context) {}
1254/// }
1255///
1256/// #[http3]
1257/// async fn standalone_http3_handler(ctx: &Context) {}
1258/// ```
1259///
1260/// The macro takes no parameters and should be applied directly to async functions
1261/// that accept a `&Context` parameter.
1262#[proc_macro_attribute]
1263pub fn http3(_attr: TokenStream, item: TokenStream) -> TokenStream {
1264    http3_macro(item, Position::Prologue)
1265}
1266
1267/// Restricts function execution to TLS-encrypted requests only.
1268///
1269/// This attribute macro ensures the decorated function only executes for requests
1270/// that use TLS/SSL encryption on the connection.
1271///
1272/// # Usage
1273///
1274/// ```rust
1275/// use hyperlane::*;
1276/// use hyperlane_macros::*;
1277///
1278/// #[route("/tls")]
1279/// struct Tls;
1280///
1281/// impl ServerHook for Tls {
1282///     async fn new(_ctx: &Context) -> Self {
1283///         Self
1284///     }
1285///
1286///     #[prologue_macros(tls, response_body("tls"))]
1287///     async fn handle(self, ctx: &Context) {}
1288/// }
1289///
1290/// impl Tls {
1291///     #[tls]
1292///     async fn tls_with_ref_self(&self, ctx: &Context) {}
1293/// }
1294///
1295/// #[tls]
1296/// async fn standalone_tls_handler(ctx: &Context) {}
1297/// ```
1298///
1299/// The macro takes no parameters and should be applied directly to async functions
1300/// that accept a `&Context` parameter.
1301#[proc_macro_attribute]
1302pub fn tls(_attr: TokenStream, item: TokenStream) -> TokenStream {
1303    tls_macro(item, Position::Prologue)
1304}
1305
1306/// Filters requests based on a boolean condition.
1307///
1308/// The function continues execution only if the provided code block returns `true`.
1309///
1310/// # Usage
1311///
1312/// ```rust
1313/// use hyperlane::*;
1314/// use hyperlane_macros::*;
1315///
1316/// #[route("/unknown_method")]
1317/// struct UnknownMethod;
1318///
1319/// impl ServerHook for UnknownMethod {
1320///     async fn new(_ctx: &Context) -> Self {
1321///         Self
1322///     }
1323///
1324///     #[prologue_macros(
1325///         filter(ctx.get_request().await.is_unknown_method()),
1326///         response_body("unknown_method")
1327///     )]
1328///     async fn handle(self, ctx: &Context) {}
1329/// }
1330/// ```
1331#[proc_macro_attribute]
1332pub fn filter(attr: TokenStream, item: TokenStream) -> TokenStream {
1333    filter_macro(attr, item, Position::Prologue)
1334}
1335
1336/// Rejects requests based on a boolean condition.
1337///
1338/// The function continues execution only if the provided code block returns `false`.
1339///
1340/// # Usage
1341///
1342/// ```rust
1343/// use hyperlane::*;
1344/// use hyperlane_macros::*;
1345///
1346/// #[response_middleware(2)]
1347/// struct ResponseMiddleware2;
1348///
1349/// impl ServerHook for ResponseMiddleware2 {
1350///     async fn new(_ctx: &Context) -> Self {
1351///         Self
1352///     }
1353///
1354///     #[prologue_macros(
1355///         reject(ctx.get_request().await.is_ws())
1356///     )]
1357///     async fn handle(self, ctx: &Context) {}
1358/// }
1359/// ```
1360#[proc_macro_attribute]
1361pub fn reject(attr: TokenStream, item: TokenStream) -> TokenStream {
1362    reject_macro(attr, item, Position::Prologue)
1363}
1364
1365/// Restricts function execution to requests with a specific host.
1366///
1367/// This attribute macro ensures the decorated function only executes when the incoming request
1368/// has a host header that matches the specified value. Requests with different or missing host headers will be filtered out.
1369///
1370/// # Usage
1371///
1372/// ```rust
1373/// use hyperlane::*;
1374/// use hyperlane_macros::*;
1375///
1376/// #[route("/host")]
1377/// struct Host;
1378///
1379/// impl ServerHook for Host {
1380///     async fn new(_ctx: &Context) -> Self {
1381///         Self
1382///     }
1383///
1384///     #[host("localhost")]
1385///     #[prologue_macros(response_body("host string literal: localhost"), send)]
1386///     async fn handle(self, ctx: &Context) {}
1387/// }
1388///
1389/// impl Host {
1390///     #[host("localhost")]
1391///     async fn host_with_ref_self(&self, ctx: &Context) {}
1392/// }
1393///
1394/// #[host("localhost")]
1395/// async fn standalone_host_handler(ctx: &Context) {}
1396/// ```
1397///
1398/// The macro accepts a string literal specifying the expected host value and should be
1399/// applied to async functions that accept a `&Context` parameter.
1400#[proc_macro_attribute]
1401pub fn host(attr: TokenStream, item: TokenStream) -> TokenStream {
1402    host_macro(attr, item, Position::Prologue)
1403}
1404
1405/// Reject requests that have no host header.
1406///
1407/// This attribute macro ensures the decorated function only executes when the incoming request
1408/// has a host header present. Requests without a host header will be filtered out.
1409///
1410/// # Usage
1411///
1412/// ```rust
1413/// use hyperlane::*;
1414/// use hyperlane_macros::*;
1415///
1416/// #[route("/reject_host")]
1417/// struct RejectHost;
1418///
1419/// impl ServerHook for RejectHost {
1420///     async fn new(_ctx: &Context) -> Self {
1421///         Self
1422///     }
1423///
1424///     #[prologue_macros(
1425///         reject_host("filter.localhost"),
1426///         response_body("host filter string literal")
1427///     )]
1428///     async fn handle(self, ctx: &Context) {}
1429/// }
1430///
1431/// impl RejectHost {
1432///     #[reject_host("filter.localhost")]
1433///     async fn reject_host_with_ref_self(&self, ctx: &Context) {}
1434/// }
1435///
1436/// #[reject_host("filter.localhost")]
1437/// async fn standalone_reject_host_handler(ctx: &Context) {}
1438/// ```
1439///
1440/// The macro takes no parameters and should be applied directly to async functions
1441/// that accept a `&Context` parameter.
1442#[proc_macro_attribute]
1443pub fn reject_host(attr: TokenStream, item: TokenStream) -> TokenStream {
1444    reject_host_macro(attr, item, Position::Prologue)
1445}
1446
1447/// Restricts function execution to requests with a specific referer.
1448///
1449/// This attribute macro ensures the decorated function only executes when the incoming request
1450/// has a referer header that matches the specified value. Requests with different or missing referer headers will be filtered out.
1451///
1452/// # Usage
1453///
1454/// ```rust
1455/// use hyperlane::*;
1456/// use hyperlane_macros::*;
1457///
1458/// #[route("/referer")]
1459/// struct Referer;
1460///
1461/// impl ServerHook for Referer {
1462///     async fn new(_ctx: &Context) -> Self {
1463///         Self
1464///     }
1465///
1466///     #[prologue_macros(
1467///         referer("http://localhost"),
1468///         response_body("referer string literal: http://localhost")
1469///     )]
1470///     async fn handle(self, ctx: &Context) {}
1471/// }
1472///
1473/// impl Referer {
1474///     #[referer("http://localhost")]
1475///     async fn referer_with_ref_self(&self, ctx: &Context) {}
1476/// }
1477///
1478/// #[referer("http://localhost")]
1479/// async fn standalone_referer_handler(ctx: &Context) {}
1480/// ```
1481///
1482/// The macro accepts a string literal specifying the expected referer value and should be
1483/// applied to async functions that accept a `&Context` parameter.
1484#[proc_macro_attribute]
1485pub fn referer(attr: TokenStream, item: TokenStream) -> TokenStream {
1486    referer_macro(attr, item, Position::Prologue)
1487}
1488
1489/// Reject requests that have a specific referer header.
1490///
1491/// This attribute macro ensures the decorated function only executes when the incoming request
1492/// does not have a referer header that matches the specified value. Requests with the matching referer header will be filtered out.
1493///
1494/// # Usage
1495///
1496/// ```rust
1497/// use hyperlane::*;
1498/// use hyperlane_macros::*;
1499///
1500/// #[route("/reject_referer")]
1501/// struct RejectReferer;
1502///
1503/// impl ServerHook for RejectReferer {
1504///     async fn new(_ctx: &Context) -> Self {
1505///         Self
1506///     }
1507///
1508///     #[prologue_macros(
1509///         reject_referer("http://localhost"),
1510///         response_body("referer filter string literal")
1511///     )]
1512///     async fn handle(self, ctx: &Context) {}
1513/// }
1514///
1515/// impl RejectReferer {
1516///     #[reject_referer("http://localhost")]
1517///     async fn reject_referer_with_ref_self(&self, ctx: &Context) {}
1518/// }
1519///
1520/// #[reject_referer("http://localhost")]
1521/// async fn standalone_reject_referer_handler(ctx: &Context) {}
1522/// ```
1523///
1524/// The macro accepts a string literal specifying the referer value to filter out and should be
1525/// applied to async functions that accept a `&Context` parameter.
1526#[proc_macro_attribute]
1527pub fn reject_referer(attr: TokenStream, item: TokenStream) -> TokenStream {
1528    reject_referer_macro(attr, item, Position::Prologue)
1529}
1530
1531/// Executes multiple specified functions before the main handler function.
1532///
1533/// This attribute macro configures multiple pre-execution hooks that run before the main function logic.
1534/// The specified hook functions will be called in the order provided, followed by the main function execution.
1535///
1536/// # Usage
1537///
1538/// ```rust
1539/// use hyperlane::*;
1540/// use hyperlane_macros::*;
1541///
1542/// struct PrologueHooks;
1543///
1544/// impl ServerHook for PrologueHooks {
1545///     async fn new(_ctx: &Context) -> Self {
1546///         Self
1547///     }
1548///
1549///     #[get]
1550///     #[http]
1551///     async fn handle(self, _ctx: &Context) {}
1552/// }
1553///
1554/// async fn prologue_hooks_fn(ctx: Context) {
1555///     let hook = PrologueHooks::new(&ctx).await;
1556///     hook.handle(&ctx).await;
1557/// }
1558///
1559/// #[route("/hook")]
1560/// struct Hook;
1561///
1562/// impl ServerHook for Hook {
1563///     async fn new(_ctx: &Context) -> Self {
1564///         Self
1565///     }
1566///
1567///     #[prologue_hooks(prologue_hooks_fn)]
1568///     #[response_body("Testing hook macro")]
1569///     async fn handle(self, ctx: &Context) {}
1570/// }
1571/// ```
1572///
1573/// The macro accepts a comma-separated list of function names as parameters. All hook functions
1574/// and the main function must accept a `Context` parameter. Avoid combining this macro with other
1575/// macros on the same function to prevent macro expansion conflicts.
1576#[proc_macro_attribute]
1577pub fn prologue_hooks(attr: TokenStream, item: TokenStream) -> TokenStream {
1578    prologue_hooks_macro(attr, item, Position::Prologue)
1579}
1580
1581/// Executes multiple specified functions after the main handler function.
1582///
1583/// This attribute macro configures multiple post-execution hooks that run after the main function logic.
1584/// The main function will execute first, followed by the specified hook functions in the order provided.
1585///
1586/// # Usage
1587///
1588/// ```rust
1589/// use hyperlane::*;
1590/// use hyperlane_macros::*;
1591///
1592/// struct EpilogueHooks;
1593///
1594/// impl ServerHook for EpilogueHooks {
1595///     async fn new(_ctx: &Context) -> Self {
1596///         Self
1597///     }
1598///
1599///     #[response_status_code(200)]
1600///     async fn handle(self, ctx: &Context) {}
1601/// }
1602///
1603/// async fn epilogue_hooks_fn(ctx: Context) {
1604///     let hook = EpilogueHooks::new(&ctx).await;
1605///     hook.handle(&ctx).await;
1606/// }
1607///
1608/// #[route("/hook")]
1609/// struct Hook;
1610///
1611/// impl ServerHook for Hook {
1612///     async fn new(_ctx: &Context) -> Self {
1613///         Self
1614///     }
1615///
1616///     #[epilogue_hooks(epilogue_hooks_fn)]
1617///     #[response_body("Testing hook macro")]
1618///     async fn handle(self, ctx: &Context) {}
1619/// }
1620/// ```
1621///
1622/// The macro accepts a comma-separated list of function names as parameters. All hook functions
1623/// and the main function must accept a `Context` parameter. Avoid combining this macro with other
1624/// macros on the same function to prevent macro expansion conflicts.
1625#[proc_macro_attribute]
1626pub fn epilogue_hooks(attr: TokenStream, item: TokenStream) -> TokenStream {
1627    epilogue_hooks_macro(attr, item, Position::Epilogue)
1628}
1629
1630/// Extracts the raw request body into a specified variable.
1631///
1632/// This attribute macro extracts the raw request body content into a variable
1633/// with the fixed type `RequestBody`. The body content is not parsed or deserialized.
1634///
1635/// # Usage
1636///
1637/// ```rust
1638/// use hyperlane::*;
1639/// use hyperlane_macros::*;
1640///
1641/// #[route("/request_body")]
1642/// struct RequestBodyRoute;
1643///
1644/// impl ServerHook for RequestBodyRoute {
1645///     async fn new(_ctx: &Context) -> Self {
1646///         Self
1647///     }
1648///
1649///     #[response_body(&format!("raw body: {raw_body:?}"))]
1650///     #[request_body(raw_body)]
1651///     async fn handle(self, ctx: &Context) {}
1652/// }
1653///
1654/// impl RequestBodyRoute {
1655///     #[request_body(raw_body)]
1656///     async fn request_body_with_ref_self(&self, ctx: &Context) {}
1657/// }
1658///
1659/// #[request_body(raw_body)]
1660/// async fn standalone_request_body_handler(ctx: &Context) {}
1661/// ```
1662///
1663/// # Multi-Parameter Usage
1664///
1665/// ```rust
1666/// use hyperlane::*;
1667/// use hyperlane_macros::*;
1668///
1669/// #[route("/multi_body")]
1670/// struct MultiBody;
1671///
1672/// impl ServerHook for MultiBody {
1673///     async fn new(_ctx: &Context) -> Self {
1674///         Self
1675///     }
1676///
1677///     #[response_body(&format!("bodies: {body1:?}, {body2:?}"))]
1678///     #[request_body(body1, body2)]
1679///     async fn handle(self, ctx: &Context) {}
1680/// }
1681/// ```
1682///
1683/// The macro accepts one or more variable names separated by commas.
1684/// Each variable will be available in the function scope as a `RequestBody` type.
1685#[proc_macro_attribute]
1686pub fn request_body(attr: TokenStream, item: TokenStream) -> TokenStream {
1687    request_body_macro(attr, item, Position::Prologue)
1688}
1689
1690/// Parses the request body as JSON into a specified variable and type.
1691///
1692/// This attribute macro extracts and deserializes the request body content as JSON into a variable
1693/// with the specified type. The body content is parsed as JSON using serde.
1694///
1695/// # Usage
1696///
1697/// ```rust
1698/// use hyperlane::*;
1699/// use hyperlane_macros::*;
1700/// use serde::{Deserialize, Serialize};
1701///
1702/// #[derive(Debug, Serialize, Deserialize, Clone)]
1703/// struct TestData {
1704///     name: String,
1705///     age: u32,
1706/// }
1707///
1708/// #[route("/request_body_json")]
1709/// struct RequestBodyJson;
1710///
1711/// impl ServerHook for RequestBodyJson {
1712///     async fn new(_ctx: &Context) -> Self {
1713///         Self
1714///     }
1715///
1716///     #[response_body(&format!("request data: {request_data_result:?}"))]
1717///     #[request_body_json(request_data_result: TestData)]
1718///     async fn handle(self, ctx: &Context) {}
1719/// }
1720///
1721/// impl RequestBodyJson {
1722///     #[request_body_json(request_data_result: TestData)]
1723///     async fn request_body_json_with_ref_self(&self, ctx: &Context) {}
1724/// }
1725///
1726/// #[request_body_json(request_data_result: TestData)]
1727/// async fn standalone_request_body_json_handler(ctx: &Context) {}
1728/// ```
1729///
1730/// # Multi-Parameter Usage
1731///
1732/// ```rust
1733/// use hyperlane::*;
1734/// use hyperlane_macros::*;
1735/// use serde::{Deserialize, Serialize};
1736///
1737/// #[derive(Debug, Serialize, Deserialize, Clone)]
1738/// struct User {
1739///     name: String,
1740/// }
1741///
1742/// #[derive(Debug, Serialize, Deserialize, Clone)]
1743/// struct Config {
1744///     debug: bool,
1745/// }
1746///
1747/// #[route("/multi_json")]
1748/// struct MultiJson;
1749///
1750/// impl ServerHook for MultiJson {
1751///     async fn new(_ctx: &Context) -> Self {
1752///         Self
1753///     }
1754///
1755///     #[response_body(&format!("user: {user:?}, config: {config:?}"))]
1756///     #[request_body_json(user: User, config: Config)]
1757///     async fn handle(self, ctx: &Context) {}
1758/// }
1759/// ```
1760///
1761/// The macro accepts one or more `variable_name: Type` pairs separated by commas.
1762/// Each variable will be available in the function scope as a `Result<Type, JsonError>`.
1763#[proc_macro_attribute]
1764pub fn request_body_json(attr: TokenStream, item: TokenStream) -> TokenStream {
1765    request_body_json_macro(attr, item, Position::Prologue)
1766}
1767
1768/// Extracts a specific attribute value into a variable.
1769///
1770/// This attribute macro retrieves a specific attribute by key and makes it available
1771/// as a typed variable from the request context.
1772///
1773/// # Usage
1774///
1775/// ```rust
1776/// use hyperlane::*;
1777/// use hyperlane_macros::*;
1778/// use serde::{Deserialize, Serialize};
1779///
1780/// const TEST_ATTRIBUTE_KEY: &str = "test_attribute_key";
1781///
1782/// #[derive(Debug, Serialize, Deserialize, Clone)]
1783/// struct TestData {
1784///     name: String,
1785///     age: u32,
1786/// }
1787///
1788/// #[route("/attribute")]
1789/// struct Attribute;
1790///
1791/// impl ServerHook for Attribute {
1792///     async fn new(_ctx: &Context) -> Self {
1793///         Self
1794///     }
1795///
1796///     #[response_body(&format!("request attribute: {request_attribute_option:?}"))]
1797///     #[attribute(TEST_ATTRIBUTE_KEY => request_attribute_option: TestData)]
1798///     async fn handle(self, ctx: &Context) {}
1799/// }
1800///
1801/// impl Attribute {
1802///     #[attribute(TEST_ATTRIBUTE_KEY => request_attribute_option: TestData)]
1803///     async fn attribute_with_ref_self(&self, ctx: &Context) {}
1804/// }
1805///
1806/// #[attribute(TEST_ATTRIBUTE_KEY => request_attribute_option: TestData)]
1807/// async fn standalone_attribute_handler(ctx: &Context) {}
1808/// ```
1809///
1810/// The macro accepts a key-to-variable mapping in the format `key => variable_name: Type`.
1811/// The variable will be available as an `Option<Type>` in the function scope.
1812///
1813/// # Multi-Parameter Usage
1814///
1815/// ```rust
1816/// use hyperlane::*;
1817/// use hyperlane_macros::*;
1818///
1819/// #[route("/multi_attr")]
1820/// struct MultiAttr;
1821///
1822/// impl ServerHook for MultiAttr {
1823///     async fn new(_ctx: &Context) -> Self {
1824///         Self
1825///     }
1826///
1827///     #[response_body(&format!("attrs: {attr1:?}, {attr2:?}"))]
1828///     #[attribute("key1" => attr1: String, "key2" => attr2: i32)]
1829///     async fn handle(self, ctx: &Context) {}
1830/// }
1831/// ```
1832///
1833/// The macro accepts multiple `key => variable_name: Type` tuples separated by commas.
1834#[proc_macro_attribute]
1835pub fn attribute(attr: TokenStream, item: TokenStream) -> TokenStream {
1836    attribute_macro(attr, item, Position::Prologue)
1837}
1838
1839/// Extracts all attributes into a HashMap variable.
1840///
1841/// This attribute macro retrieves all available attributes from the request context
1842/// and makes them available as a HashMap for comprehensive attribute access.
1843///
1844/// # Usage
1845///
1846/// ```rust
1847/// use hyperlane::*;
1848/// use hyperlane_macros::*;
1849///
1850/// #[route("/attributes")]
1851/// struct Attributes;
1852///
1853/// impl ServerHook for Attributes {
1854///     async fn new(_ctx: &Context) -> Self {
1855///         Self
1856///     }
1857///
1858///     #[response_body(&format!("request attributes: {request_attributes:?}"))]
1859///     #[attributes(request_attributes)]
1860///     async fn handle(self, ctx: &Context) {}
1861/// }
1862///
1863/// impl Attributes {
1864///     #[attributes(request_attributes)]
1865///     async fn attributes_with_ref_self(&self, ctx: &Context) {}
1866/// }
1867///
1868/// #[attributes(request_attributes)]
1869/// async fn standalone_attributes_handler(ctx: &Context) {}
1870/// ```
1871///
1872/// The macro accepts a variable name that will contain a HashMap of all attributes.
1873/// The variable will be available as a HashMap in the function scope.
1874///
1875/// # Multi-Parameter Usage
1876///
1877/// ```rust
1878/// use hyperlane::*;
1879/// use hyperlane_macros::*;
1880///
1881/// #[route("/multi_attrs")]
1882/// struct MultiAttrs;
1883///
1884/// impl ServerHook for MultiAttrs {
1885///     async fn new(_ctx: &Context) -> Self {
1886///         Self
1887///     }
1888///
1889///     #[response_body(&format!("attrs1: {attrs1:?}, attrs2: {attrs2:?}"))]
1890///     #[attributes(attrs1, attrs2)]
1891///     async fn handle(self, ctx: &Context) {}
1892/// }
1893/// ```
1894///
1895/// The macro accepts multiple variable names separated by commas.
1896#[proc_macro_attribute]
1897pub fn attributes(attr: TokenStream, item: TokenStream) -> TokenStream {
1898    attributes_macro(attr, item, Position::Prologue)
1899}
1900
1901/// Extracts a specific route parameter into a variable.
1902///
1903/// This attribute macro retrieves a specific route parameter by key and makes it
1904/// available as a variable. Route parameters are extracted from the URL path segments.
1905///
1906/// # Usage
1907///
1908/// ```rust
1909/// use hyperlane::*;
1910/// use hyperlane_macros::*;
1911///
1912/// #[route("/route_param/:test")]
1913/// struct RouteParam;
1914///
1915/// impl ServerHook for RouteParam {
1916///     async fn new(_ctx: &Context) -> Self {
1917///         Self
1918///     }
1919///
1920///     #[response_body(&format!("route param: {request_route_param:?}"))]
1921///     #[route_param("test" => request_route_param)]
1922///     async fn handle(self, ctx: &Context) {}
1923/// }
1924///
1925/// impl RouteParam {
1926///     #[route_param("test" => request_route_param)]
1927///     async fn route_param_with_ref_self(&self, ctx: &Context) {}
1928/// }
1929///
1930/// #[route_param("test" => request_route_param)]
1931/// async fn standalone_route_param_handler(ctx: &Context) {}
1932/// ```
1933///
1934/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
1935/// The variable will be available as an `Option<String>` in the function scope.
1936///
1937/// # Multi-Parameter Usage
1938///
1939/// ```rust
1940/// use hyperlane::*;
1941/// use hyperlane_macros::*;
1942///
1943/// #[route("/multi_param/:id/:name")]
1944/// struct MultiParam;
1945///
1946/// impl ServerHook for MultiParam {
1947///     async fn new(_ctx: &Context) -> Self {
1948///         Self
1949///     }
1950///
1951///     #[response_body(&format!("id: {id:?}, name: {name:?}"))]
1952///     #[route_param("id" => id, "name" => name)]
1953///     async fn handle(self, ctx: &Context) {}
1954/// }
1955/// ```
1956///
1957/// The macro accepts multiple `"key" => variable_name` pairs separated by commas.
1958#[proc_macro_attribute]
1959pub fn route_param(attr: TokenStream, item: TokenStream) -> TokenStream {
1960    route_param_macro(attr, item, Position::Prologue)
1961}
1962
1963/// Extracts all route parameters into a collection variable.
1964///
1965/// This attribute macro retrieves all available route parameters from the URL path
1966/// and makes them available as a collection for comprehensive route parameter access.
1967///
1968/// # Usage
1969///
1970/// ```rust
1971/// use hyperlane::*;
1972/// use hyperlane_macros::*;
1973///
1974/// #[route("/route_params/:test")]
1975/// struct RouteParams;
1976///
1977/// impl ServerHook for RouteParams {
1978///     async fn new(_ctx: &Context) -> Self {
1979///         Self
1980///     }
1981///
1982///     #[response_body(&format!("request route params: {request_route_params:?}"))]
1983///     #[route_params(request_route_params)]
1984///     async fn handle(self, ctx: &Context) {}
1985/// }
1986///
1987/// impl RouteParams {
1988///     #[route_params(request_route_params)]
1989///     async fn route_params_with_ref_self(&self, ctx: &Context) {}
1990/// }
1991///
1992/// #[route_params(request_route_params)]
1993/// async fn standalone_route_params_handler(ctx: &Context) {}
1994/// ```
1995///
1996/// The macro accepts a variable name that will contain all route parameters.
1997/// The variable will be available as a collection in the function scope.
1998///
1999/// # Multi-Parameter Usage
2000///
2001/// ```rust
2002/// use hyperlane::*;
2003/// use hyperlane_macros::*;
2004///
2005/// #[route("/multi_params/:id")]
2006/// struct MultiParams;
2007///
2008/// impl ServerHook for MultiParams {
2009///     async fn new(_ctx: &Context) -> Self {
2010///         Self
2011///     }
2012///
2013///     #[response_body(&format!("params1: {params1:?}, params2: {params2:?}"))]
2014///     #[route_params(params1, params2)]
2015///     async fn handle(self, ctx: &Context) {}
2016/// }
2017/// ```
2018///
2019/// The macro accepts multiple variable names separated by commas.
2020#[proc_macro_attribute]
2021pub fn route_params(attr: TokenStream, item: TokenStream) -> TokenStream {
2022    route_params_macro(attr, item, Position::Prologue)
2023}
2024
2025/// Extracts a specific request query parameter into a variable.
2026///
2027/// This attribute macro retrieves a specific request query parameter by key and makes it
2028/// available as a variable. Query parameters are extracted from the URL request query string.
2029///
2030/// # Usage
2031///
2032/// ```rust
2033/// use hyperlane::*;
2034/// use hyperlane_macros::*;
2035///
2036/// #[route("/request_query")]
2037/// struct RequestQuery;
2038///
2039/// impl ServerHook for RequestQuery {
2040///     async fn new(_ctx: &Context) -> Self {
2041///         Self
2042///     }
2043///
2044///     #[prologue_macros(
2045///         request_query("test" => request_query_option),
2046///         response_body(&format!("request query: {request_query_option:?}")),
2047///         send
2048///     )]
2049///     async fn handle(self, ctx: &Context) {}
2050/// }
2051///
2052/// impl RequestQuery {
2053///     #[request_query("test" => request_query_option)]
2054///     async fn request_query_with_ref_self(&self, ctx: &Context) {}
2055/// }
2056///
2057/// #[request_query("test" => request_query_option)]
2058/// async fn standalone_request_query_handler(ctx: &Context) {}
2059/// ```
2060///
2061/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
2062/// The variable will be available as an `Option<String>` in the function scope.
2063///
2064/// Supports multiple parameters: `#[request_query("k1" => v1, "k2" => v2)]`
2065#[proc_macro_attribute]
2066pub fn request_query(attr: TokenStream, item: TokenStream) -> TokenStream {
2067    request_query_macro(attr, item, Position::Prologue)
2068}
2069
2070/// Extracts all request query parameters into a collection variable.
2071///
2072/// This attribute macro retrieves all available request query parameters from the URL request query string
2073/// and makes them available as a collection for comprehensive request query parameter access.
2074///
2075/// # Usage
2076///
2077/// ```rust
2078/// use hyperlane::*;
2079/// use hyperlane_macros::*;
2080///
2081/// #[route("/request_querys")]
2082/// struct RequestQuerys;
2083///
2084/// impl ServerHook for RequestQuerys {
2085///     async fn new(_ctx: &Context) -> Self {
2086///         Self
2087///     }
2088///
2089///     #[prologue_macros(
2090///         request_querys(request_querys),
2091///         response_body(&format!("request querys: {request_querys:?}")),
2092///         send
2093///     )]
2094///     async fn handle(self, ctx: &Context) {}
2095/// }
2096///
2097/// impl RequestQuerys {
2098///     #[request_querys(request_querys)]
2099///     async fn request_querys_with_ref_self(&self, ctx: &Context) {}
2100/// }
2101///
2102/// #[request_querys(request_querys)]
2103/// async fn standalone_request_querys_handler(ctx: &Context) {}
2104/// ```
2105///
2106/// The macro accepts a variable name that will contain all request query parameters.
2107/// The variable will be available as a collection in the function scope.
2108///
2109/// Supports multiple parameters: `#[request_querys(querys1, querys2)]`
2110#[proc_macro_attribute]
2111pub fn request_querys(attr: TokenStream, item: TokenStream) -> TokenStream {
2112    request_querys_macro(attr, item, Position::Prologue)
2113}
2114
2115/// Extracts a specific HTTP request header into a variable.
2116///
2117/// This attribute macro retrieves a specific HTTP request header by name and makes it
2118/// available as a variable. Header values are extracted from the request request headers collection.
2119///
2120/// # Usage
2121///
2122/// ```rust
2123/// use hyperlane::*;
2124/// use hyperlane_macros::*;
2125///
2126/// #[route("/request_header")]
2127/// struct RequestHeader;
2128///
2129/// impl ServerHook for RequestHeader {
2130///     async fn new(_ctx: &Context) -> Self {
2131///         Self
2132///     }
2133///
2134///     #[prologue_macros(
2135///         request_header(HOST => request_header_option),
2136///         response_body(&format!("request header: {request_header_option:?}")),
2137///         send
2138///     )]
2139///     async fn handle(self, ctx: &Context) {}
2140/// }
2141///
2142/// impl RequestHeader {
2143///     #[request_header(HOST => request_header_option)]
2144///     async fn request_header_with_ref_self(&self, ctx: &Context) {}
2145/// }
2146///
2147/// #[request_header(HOST => request_header_option)]
2148/// async fn standalone_request_header_handler(ctx: &Context) {}
2149/// ```
2150///
2151/// The macro accepts a request header name-to-variable mapping in the format `HEADER_NAME => variable_name`
2152/// or `"Header-Name" => variable_name`. The variable will be available as an `Option<String>`.
2153#[proc_macro_attribute]
2154pub fn request_header(attr: TokenStream, item: TokenStream) -> TokenStream {
2155    request_header_macro(attr, item, Position::Prologue)
2156}
2157
2158/// Extracts all HTTP request headers into a collection variable.
2159///
2160/// This attribute macro retrieves all available HTTP request headers from the request
2161/// and makes them available as a collection for comprehensive request header access.
2162///
2163/// # Usage
2164///
2165/// ```rust
2166/// use hyperlane::*;
2167/// use hyperlane_macros::*;
2168///
2169/// #[route("/request_headers")]
2170/// struct RequestHeaders;
2171///
2172/// impl ServerHook for RequestHeaders {
2173///     async fn new(_ctx: &Context) -> Self {
2174///         Self
2175///     }
2176///
2177///     #[prologue_macros(
2178///         request_headers(request_headers),
2179///         response_body(&format!("request headers: {request_headers:?}")),
2180///         send
2181///     )]
2182///     async fn handle(self, ctx: &Context) {}
2183/// }
2184///
2185/// impl RequestHeaders {
2186///     #[request_headers(request_headers)]
2187///     async fn request_headers_with_ref_self(&self, ctx: &Context) {}
2188/// }
2189///
2190/// #[request_headers(request_headers)]
2191/// async fn standalone_request_headers_handler(ctx: &Context) {}
2192/// ```
2193///
2194/// The macro accepts a variable name that will contain all HTTP request headers.
2195/// The variable will be available as a collection in the function scope.
2196#[proc_macro_attribute]
2197pub fn request_headers(attr: TokenStream, item: TokenStream) -> TokenStream {
2198    request_headers_macro(attr, item, Position::Prologue)
2199}
2200
2201/// Extracts a specific cookie value or all cookies into a variable.
2202///
2203/// This attribute macro supports two syntaxes:
2204/// 1. `cookie(key => variable_name)` - Extract a specific cookie value by key
2205/// 2. `cookie(variable_name)` - Extract all cookies as a raw string
2206///
2207/// # Usage
2208///
2209/// ```rust
2210/// use hyperlane::*;
2211/// use hyperlane_macros::*;
2212///
2213/// #[route("/cookie")]
2214/// struct Cookie;
2215///
2216/// impl ServerHook for Cookie {
2217///     async fn new(_ctx: &Context) -> Self {
2218///         Self
2219///     }
2220///
2221///     #[response_body(&format!("Session cookie: {session_cookie1_option:?}, {session_cookie2_option:?}"))]
2222///     #[request_cookie("test1" => session_cookie1_option, "test2" => session_cookie2_option)]
2223///     async fn handle(self, ctx: &Context) {}
2224/// }
2225///
2226/// impl Cookie {
2227///     #[response_body(&format!("Session cookie: {session_cookie1_option:?}, {session_cookie2_option:?}"))]
2228///     #[request_cookie("test1" => session_cookie1_option, "test2" => session_cookie2_option)]
2229///     async fn request_cookie_with_ref_self(&self, ctx: &Context) {}
2230/// }
2231///
2232/// #[response_body(&format!("Session cookie: {session_cookie1_option:?}, {session_cookie2_option:?}"))]
2233/// #[request_cookie("test1" => session_cookie1_option, "test2" => session_cookie2_option)]
2234/// async fn standalone_request_cookie_handler(ctx: &Context) {}
2235/// ```
2236///
2237/// For specific cookie extraction, the variable will be available as `Option<String>`.
2238/// For all cookies extraction, the variable will be available as `String`.
2239#[proc_macro_attribute]
2240pub fn request_cookie(attr: TokenStream, item: TokenStream) -> TokenStream {
2241    request_cookie_macro(attr, item, Position::Prologue)
2242}
2243
2244/// Extracts all cookies as a raw string into a variable.
2245///
2246/// This attribute macro retrieves the entire Cookie header from the request and makes it
2247/// available as a String variable. If no Cookie header is present, an empty string is used.
2248///
2249/// # Usage
2250///
2251/// ```rust
2252/// use hyperlane::*;
2253/// use hyperlane_macros::*;
2254///
2255/// #[route("/cookies")]
2256/// struct Cookies;
2257///
2258/// impl ServerHook for Cookies {
2259///     async fn new(_ctx: &Context) -> Self {
2260///         Self
2261///     }
2262///
2263///     #[response_body(&format!("All cookies: {cookie_value:?}"))]
2264///     #[request_cookies(cookie_value)]
2265///     async fn handle(self, ctx: &Context) {}
2266/// }
2267///
2268/// impl Cookies {
2269///     #[request_cookies(cookie_value)]
2270///     async fn request_cookies_with_ref_self(&self, ctx: &Context) {}
2271/// }
2272///
2273/// #[request_cookies(cookie_value)]
2274/// async fn standalone_request_cookies_handler(ctx: &Context) {}
2275/// ```
2276///
2277/// The macro accepts a variable name that will contain the Cookie header value.
2278/// The variable will be available as a String in the function scope.
2279#[proc_macro_attribute]
2280pub fn request_cookies(attr: TokenStream, item: TokenStream) -> TokenStream {
2281    request_cookies_macro(attr, item, Position::Prologue)
2282}
2283
2284/// Extracts the HTTP request version into a variable.
2285///
2286/// This attribute macro retrieves the HTTP version from the request and makes it
2287/// available as a variable. The version represents the HTTP protocol version used.
2288///
2289/// # Usage
2290///
2291/// ```rust
2292/// use hyperlane::*;
2293/// use hyperlane_macros::*;
2294///
2295/// #[route("/request_version")]
2296/// struct RequestVersionTest;
2297///
2298/// impl ServerHook for RequestVersionTest {
2299///     async fn new(_ctx: &Context) -> Self {
2300///         Self
2301///     }
2302///
2303///     #[response_body(&format!("HTTP Version: {http_version}"))]
2304///     #[request_version(http_version)]
2305///     async fn handle(self, ctx: &Context) {}
2306/// }
2307///
2308/// impl RequestVersionTest {
2309///     #[request_version(http_version)]
2310///     async fn request_version_with_ref_self(&self, ctx: &Context) {}
2311/// }
2312///
2313/// #[request_version(http_version)]
2314/// async fn standalone_request_version_handler(ctx: &Context) {}
2315/// ```
2316///
2317/// The macro accepts a variable name that will contain the HTTP request version.
2318/// The variable will be available as a RequestVersion type in the function scope.
2319#[proc_macro_attribute]
2320pub fn request_version(attr: TokenStream, item: TokenStream) -> TokenStream {
2321    request_version_macro(attr, item, Position::Prologue)
2322}
2323
2324/// Extracts the HTTP request path into a variable.
2325///
2326/// This attribute macro retrieves the request path from the HTTP request and makes it
2327/// available as a variable. The path represents the URL path portion of the request.
2328///
2329/// # Usage
2330///
2331/// ```rust
2332/// use hyperlane::*;
2333/// use hyperlane_macros::*;
2334///
2335/// #[route("/request_path")]
2336/// struct RequestPathTest;
2337///
2338/// impl ServerHook for RequestPathTest {
2339///     async fn new(_ctx: &Context) -> Self {
2340///         Self
2341///     }
2342///
2343///     #[response_body(&format!("Request Path: {request_path}"))]
2344///     #[request_path(request_path)]
2345///     async fn handle(self, ctx: &Context) {}
2346/// }
2347///
2348/// impl RequestPathTest {
2349///     #[request_path(request_path)]
2350///     async fn request_path_with_ref_self(&self, ctx: &Context) {}
2351/// }
2352///
2353/// #[request_path(request_path)]
2354/// async fn standalone_request_path_handler(ctx: &Context) {}
2355/// ```
2356///
2357/// The macro accepts a variable name that will contain the HTTP request path.
2358/// The variable will be available as a RequestPath type in the function scope.
2359#[proc_macro_attribute]
2360pub fn request_path(attr: TokenStream, item: TokenStream) -> TokenStream {
2361    request_path_macro(attr, item, Position::Prologue)
2362}
2363
2364/// Creates a new instance of a specified type with a given variable name.
2365///
2366/// This attribute macro generates an instance initialization at the beginning of the function.
2367///
2368/// # Usage
2369///
2370/// ```rust,no_run
2371/// use hyperlane::*;
2372/// use hyperlane_macros::*;
2373///
2374/// #[hyperlane(server: Server)]
2375/// #[hyperlane(config: ServerConfig)]
2376/// #[tokio::main]
2377/// async fn main() {
2378///     config.disable_nodelay().await;
2379///     server.config(config).await;
2380///     let server_hook: ServerControlHook = server.run().await.unwrap_or_default();
2381///     server_hook.wait().await;
2382/// }
2383/// ```
2384///
2385/// The macro accepts a `variable_name: Type` pair.
2386/// The variable will be available as an instance of the specified type in the function scope.
2387#[proc_macro_attribute]
2388pub fn hyperlane(attr: TokenStream, item: TokenStream) -> TokenStream {
2389    hyperlane_macro(attr, item)
2390}
2391
2392/// Registers a function as a route handler.
2393///
2394/// This attribute macro registers the decorated function as a route handler for a given path.
2395/// This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
2396///
2397/// # Usage
2398///
2399/// ```rust
2400/// use hyperlane::*;
2401/// use hyperlane_macros::*;
2402///
2403/// #[route("/response")]
2404/// struct Response;
2405///
2406/// impl ServerHook for Response {
2407///     async fn new(_ctx: &Context) -> Self {
2408///         Self
2409///     }
2410///
2411///     #[response_body("response")]
2412///     async fn handle(self, ctx: &Context) {}
2413/// }
2414/// ```
2415///
2416/// # Parameters
2417///
2418/// - `path`: String literal defining the route path
2419///
2420/// # Dependencies
2421///
2422/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
2423#[proc_macro_attribute]
2424pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
2425    route_macro(attr, item)
2426}
2427
2428/// Registers a function as a request middleware.
2429///
2430/// This attribute macro registers the decorated function to be executed as a middleware
2431/// for incoming requests. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
2432///
2433/// # Note
2434///
2435/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
2436///
2437/// # Usage
2438///
2439/// ```rust
2440/// use hyperlane::*;
2441/// use hyperlane_macros::*;
2442///
2443/// #[request_middleware]
2444/// struct RequestMiddleware;
2445///
2446/// impl ServerHook for RequestMiddleware {
2447///     async fn new(_ctx: &Context) -> Self {
2448///         Self
2449///     }
2450///
2451///     #[epilogue_macros(
2452///         response_status_code(200),
2453///         response_version(HttpVersion::HTTP1_1),
2454///         response_header(SERVER => HYPERLANE)
2455///     )]
2456///     async fn handle(self, ctx: &Context) {}
2457/// }
2458/// ```
2459///
2460/// # Dependencies
2461///
2462/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
2463#[proc_macro_attribute]
2464pub fn request_middleware(attr: TokenStream, item: TokenStream) -> TokenStream {
2465    request_middleware_macro(attr, item)
2466}
2467
2468/// Registers a function as a response middleware.
2469///
2470/// This attribute macro registers the decorated function to be executed as a middleware
2471/// for outgoing responses. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
2472///
2473/// # Note
2474///
2475/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
2476///
2477/// # Usage
2478///
2479/// ```rust
2480/// use hyperlane::*;
2481/// use hyperlane_macros::*;
2482///
2483/// #[response_middleware]
2484/// struct ResponseMiddleware1;
2485///
2486/// impl ServerHook for ResponseMiddleware1 {
2487///     async fn new(_ctx: &Context) -> Self {
2488///         Self
2489///     }
2490///
2491///     async fn handle(self, ctx: &Context) {}
2492/// }
2493/// ```
2494///
2495/// # Dependencies
2496///
2497/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
2498#[proc_macro_attribute]
2499pub fn response_middleware(attr: TokenStream, item: TokenStream) -> TokenStream {
2500    response_middleware_macro(attr, item)
2501}
2502
2503/// Registers a function as a panic hook.
2504///
2505/// This attribute macro registers the decorated function to handle panics that occur
2506/// during request processing. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
2507///
2508/// # Note
2509///
2510/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
2511///
2512/// # Usage
2513///
2514/// ```rust
2515/// use hyperlane::*;
2516/// use hyperlane_macros::*;
2517///
2518/// #[panic_hook]
2519/// #[panic_hook(1)]
2520/// #[panic_hook("2")]
2521/// struct PanicHook;
2522///
2523/// impl ServerHook for PanicHook {
2524///     async fn new(_ctx: &Context) -> Self {
2525///         Self
2526///     }
2527///
2528///     #[epilogue_macros(response_body("panic_hook"), send)]
2529///     async fn handle(self, ctx: &Context) {}
2530/// }
2531/// ```
2532///
2533/// # Dependencies
2534///
2535/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
2536#[proc_macro_attribute]
2537pub fn panic_hook(attr: TokenStream, item: TokenStream) -> TokenStream {
2538    panic_hook_macro(attr, item)
2539}
2540
2541/// Injects a list of macros before the decorated function.
2542///
2543/// The macros are applied in head-insertion order, meaning the first macro in the list
2544/// is the outermost macro.
2545///
2546/// # Usage
2547///
2548/// ```rust
2549/// use hyperlane::*;
2550/// use hyperlane_macros::*;
2551///
2552/// #[route("/post")]
2553/// struct Post;
2554///
2555/// impl ServerHook for Post {
2556///     async fn new(_ctx: &Context) -> Self {
2557///         Self
2558///     }
2559///
2560///     #[prologue_macros(post, response_body("post"), send)]
2561///     async fn handle(self, ctx: &Context) {}
2562/// }
2563/// ```
2564#[proc_macro_attribute]
2565pub fn prologue_macros(attr: TokenStream, item: TokenStream) -> TokenStream {
2566    prologue_macros_macro(attr, item)
2567}
2568
2569/// Injects a list of macros after the decorated function.
2570///
2571/// The macros are applied in tail-insertion order, meaning the last macro in the list
2572/// is the outermost macro.
2573///
2574/// # Usage
2575///
2576/// ```rust
2577/// use hyperlane::*;
2578/// use hyperlane_macros::*;
2579///
2580/// #[response_middleware(2)]
2581/// struct ResponseMiddleware2;
2582///
2583/// impl ServerHook for ResponseMiddleware2 {
2584///     async fn new(_ctx: &Context) -> Self {
2585///         Self
2586///     }
2587///
2588///     #[epilogue_macros(send, flush)]
2589///     async fn handle(self, ctx: &Context) {}
2590/// }
2591/// ```
2592#[proc_macro_attribute]
2593pub fn epilogue_macros(attr: TokenStream, item: TokenStream) -> TokenStream {
2594    epilogue_macros_macro(attr, item)
2595}
2596
2597/// Sends only the response body with data after function execution.
2598///
2599/// This attribute macro ensures that only the response body is automatically sent
2600/// to the client after the function completes, handling request headers separately,
2601/// with the specified data.
2602///
2603/// # Usage
2604///
2605/// ```rust
2606/// use hyperlane::*;
2607/// use hyperlane_macros::*;
2608///
2609/// #[route("/send_body_with_data")]
2610/// struct SendBodyWithData;
2611///
2612/// impl ServerHook for SendBodyWithData {
2613///     async fn new(_ctx: &Context) -> Self {
2614///         Self
2615///     }
2616///
2617///     #[epilogue_macros(send_body_with_data("Response body content"))]
2618///     async fn handle(self, ctx: &Context) {}
2619/// }
2620/// ```
2621///
2622/// The macro accepts data to send and should be applied to async functions
2623/// that accept a `&Context` parameter.
2624#[proc_macro_attribute]
2625pub fn send_body_with_data(attr: TokenStream, item: TokenStream) -> TokenStream {
2626    send_body_with_data_macro(attr, item, Position::Epilogue)
2627}
2628
2629/// Wraps function body with WebSocket stream processing.
2630///
2631/// This attribute macro generates code that wraps the function body with a check to see if
2632/// data can be read from a WebSocket stream. The function body is only executed
2633/// if data is successfully read from the stream.
2634///
2635/// This attribute macro generates code that wraps the function body with a check to see if
2636/// data can be read from a WebSocket stream. The function body is only executed
2637/// if data is successfully read from the stream.
2638///
2639/// # Arguments
2640///
2641/// - `TokenStream`: The buffer to read from the WebSocket stream.
2642/// - `TokenStream`: The function item to be modified
2643///
2644/// # Returns
2645///
2646/// Returns a TokenStream containing the modified function with WebSocket stream processing logic.
2647///
2648/// # Examples
2649///
2650/// Using no parameters (default buffer size):
2651/// ```rust
2652/// use hyperlane::*;
2653/// use hyperlane_macros::*;
2654///
2655/// #[route("/ws1")]
2656/// struct Websocket1;
2657///
2658/// impl ServerHook for Websocket1 {
2659///     async fn new(_ctx: &Context) -> Self {
2660///         Self
2661///     }
2662///
2663///     #[ws]
2664///     #[ws_from_stream]
2665///     async fn handle(self, ctx: &Context) {
2666///         let body: RequestBody = ctx.get_request_body().await;
2667///         let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
2668///         ctx.send_body_list_with_data(&body_list).await.unwrap();
2669///     }
2670/// }
2671/// ```
2672///
2673/// Using only buffer size:
2674/// ```rust
2675/// use hyperlane::*;
2676/// use hyperlane_macros::*;
2677///
2678/// #[route("/ws5")]
2679/// struct Websocket5;
2680///
2681/// impl ServerHook for Websocket5 {
2682///     async fn new(_ctx: &Context) -> Self {
2683///         Self
2684///     }
2685///
2686///     #[ws]
2687///     #[ws_from_stream(1024)]
2688///     async fn handle(self, ctx: &Context) {
2689///         let body: RequestBody = ctx.get_request_body().await;
2690///         let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
2691///         ctx.send_body_list_with_data(&body_list).await.unwrap();
2692///     }
2693/// }
2694/// ```
2695///
2696/// Using variable name to store request data:
2697/// ```rust
2698/// use hyperlane::*;
2699/// use hyperlane_macros::*;
2700///
2701/// #[route("/ws2")]
2702/// struct Websocket2;
2703///
2704/// impl ServerHook for Websocket2 {
2705///     async fn new(_ctx: &Context) -> Self {
2706///         Self
2707///     }
2708///
2709///     #[ws]
2710///     #[ws_from_stream(request)]
2711///     async fn handle(self, ctx: &Context) {
2712///         let body: &RequestBody = &request.get_body();
2713///         let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(body);
2714///         ctx.send_body_list_with_data(&body_list).await.unwrap();
2715///     }
2716/// }
2717/// ```
2718///
2719/// Using buffer size and variable name:
2720/// ```rust
2721/// use hyperlane::*;
2722/// use hyperlane_macros::*;
2723///
2724/// #[route("/ws3")]
2725/// struct Websocket3;
2726///
2727/// impl ServerHook for Websocket3 {
2728///     async fn new(_ctx: &Context) -> Self {
2729///         Self
2730///     }
2731///
2732///     #[ws]
2733///     #[ws_from_stream(1024, request)]
2734///     async fn handle(self, ctx: &Context) {
2735///         let body: &RequestBody = request.get_body();
2736///         let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
2737///         ctx.send_body_list_with_data(&body_list).await.unwrap();
2738///     }
2739/// }
2740/// ```
2741///
2742/// Using variable name and buffer size (reversed order):
2743/// ```rust
2744/// use hyperlane::*;
2745/// use hyperlane_macros::*;
2746///
2747/// #[route("/ws4")]
2748/// struct Websocket4;
2749///
2750/// impl ServerHook for Websocket4 {
2751///     async fn new(_ctx: &Context) -> Self {
2752///         Self
2753///     }
2754///
2755///     #[ws]
2756///     #[ws_from_stream(request, 1024)]
2757///     async fn handle(self, ctx: &Context) {
2758///         let body: &RequestBody = request.get_body();
2759///         let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
2760///         ctx.send_body_list_with_data(&body_list).await.unwrap();
2761///     }
2762/// }
2763///
2764/// impl Websocket4 {
2765///     #[ws_from_stream(request)]
2766///     async fn ws_from_stream_with_ref_self(&self, ctx: &Context) {}
2767/// }
2768///
2769/// #[ws_from_stream]
2770/// async fn standalone_ws_from_stream_handler(ctx: &Context) {}
2771/// ```
2772#[proc_macro_attribute]
2773pub fn ws_from_stream(attr: TokenStream, item: TokenStream) -> TokenStream {
2774    ws_from_stream_macro(attr, item)
2775}
2776
2777/// Wraps function body with HTTP stream processing.
2778///
2779/// This attribute macro generates code that wraps the function body with a check to see if
2780/// data can be read from an HTTP stream. The function body is only executed
2781/// if data is successfully read from the stream.
2782///
2783/// This attribute macro generates code that wraps the function body with a check to see if
2784/// data can be read from an HTTP stream. The function body is only executed
2785/// if data is successfully read from the stream.
2786///
2787/// # Arguments
2788///
2789/// - `TokenStream`: The buffer to read from the HTTP stream.
2790/// - `TokenStream`: The function item to be modified
2791///
2792/// # Returns
2793///
2794/// Returns a TokenStream containing the modified function with HTTP stream processing logic.
2795///
2796/// # Examples
2797///
2798/// Using with epilogue_macros:
2799/// ```rust
2800/// use hyperlane::*;
2801/// use hyperlane_macros::*;
2802///
2803/// #[route("/request_query")]
2804/// struct RequestQuery;
2805///
2806/// impl ServerHook for RequestQuery {
2807///     async fn new(_ctx: &Context) -> Self {
2808///         Self
2809///     }
2810///
2811///     #[epilogue_macros(
2812///         request_query("test" => request_query_option),
2813///         response_body(&format!("request query: {request_query_option:?}")),
2814///         send,
2815///         http_from_stream(1024)
2816///     )]
2817///     async fn handle(self, ctx: &Context) {}
2818/// }
2819/// ```
2820///
2821/// Using with variable name:
2822/// ```rust
2823/// use hyperlane::*;
2824/// use hyperlane_macros::*;
2825///
2826/// #[route("/http_from_stream")]
2827/// struct HttpFromStreamTest;
2828///
2829/// impl ServerHook for HttpFromStreamTest {
2830///     async fn new(_ctx: &Context) -> Self {
2831///         Self
2832///     }
2833///
2834///     #[epilogue_macros(
2835///         http_from_stream(_request)
2836///     )]
2837///     async fn handle(self, ctx: &Context) {}
2838/// }
2839///
2840/// impl HttpFromStreamTest {
2841///     #[http_from_stream(_request)]
2842///     async fn http_from_stream_with_ref_self(&self, ctx: &Context) {}
2843/// }
2844///
2845/// #[http_from_stream]
2846/// async fn standalone_http_from_stream_handler(ctx: &Context) {}
2847/// ```
2848#[proc_macro_attribute]
2849pub fn http_from_stream(attr: TokenStream, item: TokenStream) -> TokenStream {
2850    http_from_stream_macro(attr, item)
2851}