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