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 ::hyperlane::inventory;
53pub(crate) use proc_macro::TokenStream;
54pub(crate) use proc_macro2::TokenStream as TokenStream2;
55pub(crate) use quote::quote;
56pub(crate) use syn::{
57 Ident, Token,
58 parse::{Parse, ParseStream, Parser, Result},
59 punctuated::Punctuated,
60 token::Comma,
61 *,
62};
63
64inventory::collect!(InjectableMacro);
65
66/// Wraps function body with WebSocket stream processing.
67///
68/// This attribute macro generates code that wraps the function body with a check to see if
69/// data can be read from a WebSocket stream. The function body is only executed
70/// if data is successfully read from the stream.
71///
72/// This attribute macro generates code that wraps the function body with a check to see if
73/// data can be read from a WebSocket stream. The function body is only executed
74/// if data is successfully read from the stream.
75///
76/// # Arguments
77///
78/// - `TokenStream`: The buffer to read from the WebSocket stream.
79/// - `TokenStream`: The function item to be modified
80///
81/// # Returns
82///
83/// Returns a TokenStream containing the modified function with WebSocket stream processing logic.
84///
85/// # Examples
86///
87/// Using no parameters (default buffer size):
88///
89/// ```rust
90/// use hyperlane::*;
91/// use hyperlane_macros::*;
92///
93/// #[route("/ws")]
94/// struct Websocket;
95///
96/// impl ServerHook for Websocket {
97/// async fn new(_ctx: &Context) -> Self {
98/// Self
99/// }
100///
101/// #[ws]
102/// #[ws_from_stream]
103/// async fn handle(self, ctx: &Context) {
104/// let body: RequestBody = ctx.get_request_body().await;
105/// let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
106/// ctx.send_body_list_with_data(&body_list).await;
107/// }
108/// }
109/// ```
110///
111/// Using only request config:
112///
113/// ```rust
114/// use hyperlane::*;
115/// use hyperlane_macros::*;
116///
117/// #[route("/ws")]
118/// struct Websocket;
119///
120/// impl ServerHook for Websocket {
121/// async fn new(_ctx: &Context) -> Self {
122/// Self
123/// }
124///
125/// #[ws]
126/// #[ws_from_stream(RequestConfig::default())]
127/// async fn handle(self, ctx: &Context) {
128/// let body: RequestBody = ctx.get_request_body().await;
129/// let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
130/// ctx.send_body_list_with_data(&body_list).await;
131/// }
132/// }
133/// ```
134///
135/// Using variable name to store request data:
136///
137/// ```rust
138/// use hyperlane::*;
139/// use hyperlane_macros::*;
140///
141/// #[route("/ws")]
142/// struct Websocket;
143///
144/// impl ServerHook for Websocket {
145/// async fn new(_ctx: &Context) -> Self {
146/// Self
147/// }
148///
149/// #[ws]
150/// #[ws_from_stream(request)]
151/// async fn handle(self, ctx: &Context) {
152/// let body: &RequestBody = &request.get_body();
153/// let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(body);
154/// ctx.send_body_list_with_data(&body_list).await;
155/// }
156/// }
157/// ```
158///
159/// Using request config and variable name:
160///
161/// ```rust
162/// use hyperlane::*;
163/// use hyperlane_macros::*;
164///
165/// #[route("/ws")]
166/// struct Websocket;
167///
168/// impl ServerHook for Websocket {
169/// async fn new(_ctx: &Context) -> Self {
170/// Self
171/// }
172///
173/// #[ws]
174/// #[ws_from_stream(RequestConfig::default(), request)]
175/// async fn handle(self, ctx: &Context) {
176/// let body: &RequestBody = request.get_body();
177/// let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
178/// ctx.send_body_list_with_data(&body_list).await;
179/// }
180/// }
181/// ```
182///
183/// Using variable name and request config (reversed order):
184///
185/// ```rust
186/// use hyperlane::*;
187/// use hyperlane_macros::*;
188///
189/// #[route("/ws")]
190/// struct Websocket;
191///
192/// impl ServerHook for Websocket {
193/// async fn new(_ctx: &Context) -> Self {
194/// Self
195/// }
196///
197/// #[ws]
198/// #[ws_from_stream(request, RequestConfig::default())]
199/// async fn handle(self, ctx: &Context) {
200/// let body: &RequestBody = request.get_body();
201/// let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
202/// ctx.send_body_list_with_data(&body_list).await;
203/// }
204/// }
205///
206/// impl Websocket {
207/// #[ws_from_stream(request)]
208/// async fn ws_from_stream_with_ref_self(&self, ctx: &Context) {}
209/// }
210///
211/// #[ws_from_stream]
212/// async fn standalone_ws_from_stream_handler(ctx: &Context) {}
213/// ```
214#[proc_macro_attribute]
215pub fn ws_from_stream(attr: TokenStream, item: TokenStream) -> TokenStream {
216 ws_from_stream_macro(attr, item)
217}
218
219/// Wraps function body with HTTP stream processing.
220///
221/// This attribute macro generates code that wraps the function body with a check to see if
222/// data can be read from an HTTP stream. The function body is only executed
223/// if data is successfully read from the stream.
224///
225/// This attribute macro generates code that wraps the function body with a check to see if
226/// data can be read from an HTTP stream. The function body is only executed
227/// if data is successfully read from the stream.
228///
229/// # Arguments
230///
231/// - `TokenStream`: The buffer to read from the HTTP stream.
232/// - `TokenStream`: The function item to be modified
233///
234/// # Returns
235///
236/// Returns a TokenStream containing the modified function with HTTP stream processing logic.
237///
238/// # Examples
239///
240/// Using with epilogue_macros:
241///
242/// ```rust
243/// use hyperlane::*;
244/// use hyperlane_macros::*;
245///
246/// #[route("/http_from_stream")]
247/// struct HttpFromStreamTest;
248///
249/// impl ServerHook for HttpFromStreamTest {
250/// async fn new(_ctx: &Context) -> Self {
251/// Self
252/// }
253///
254/// #[epilogue_macros(
255/// request_query("test" => request_query_option),
256/// response_body(&format!("request query: {request_query_option:?}")),
257/// send,
258/// http_from_stream(RequestConfig::default())
259/// )]
260/// async fn handle(self, ctx: &Context) {}
261/// }
262/// ```
263///
264/// Using with variable name:
265///
266/// ```rust
267/// use hyperlane::*;
268/// use hyperlane_macros::*;
269///
270/// #[route("/http_from_stream")]
271/// struct HttpFromStreamTest;
272///
273/// impl ServerHook for HttpFromStreamTest {
274/// async fn new(_ctx: &Context) -> Self {
275/// Self
276/// }
277///
278/// #[epilogue_macros(
279/// http_from_stream(_request)
280/// )]
281/// async fn handle(self, ctx: &Context) {}
282/// }
283///
284/// impl HttpFromStreamTest {
285/// #[http_from_stream(_request)]
286/// async fn http_from_stream_with_ref_self(&self, ctx: &Context) {}
287/// }
288///
289/// #[http_from_stream]
290/// async fn standalone_http_from_stream_handler(ctx: &Context) {}
291/// ```
292#[proc_macro_attribute]
293pub fn http_from_stream(attr: TokenStream, item: TokenStream) -> TokenStream {
294 http_from_stream_macro(attr, item)
295}
296
297/// Restricts function execution to HTTP GET requests only.
298///
299/// This attribute macro ensures the decorated function only executes when the incoming request
300/// uses the GET HTTP method. Requests with other methods will be filtered out.
301///
302/// # Usage
303///
304/// ```rust
305/// use hyperlane::*;
306/// use hyperlane_macros::*;
307///
308/// #[route("/get")]
309/// struct Get;
310///
311/// impl ServerHook for Get {
312/// async fn new(_ctx: &Context) -> Self {
313/// Self
314/// }
315///
316/// #[prologue_macros(get, response_body("get"))]
317/// async fn handle(self, ctx: &Context) {}
318/// }
319///
320/// impl Get {
321/// #[get]
322/// async fn get_with_ref_self(&self, ctx: &Context) {}
323/// }
324///
325/// #[get]
326/// async fn standalone_get_handler(ctx: &Context) {}
327/// ```
328///
329/// The macro takes no parameters and should be applied directly to async functions
330/// that accept a `&Context` parameter.
331#[proc_macro_attribute]
332pub fn get(_attr: TokenStream, item: TokenStream) -> TokenStream {
333 get_handler(item, Position::Prologue)
334}
335
336/// Restricts function execution to HTTP POST requests only.
337///
338/// This attribute macro ensures the decorated function only executes when the incoming request
339/// uses the POST HTTP method. Requests with other methods will be filtered out.
340///
341/// # Usage
342///
343/// ```rust
344/// use hyperlane::*;
345/// use hyperlane_macros::*;
346///
347/// #[route("/post")]
348/// struct Post;
349///
350/// impl ServerHook for Post {
351/// async fn new(_ctx: &Context) -> Self {
352/// Self
353/// }
354///
355/// #[prologue_macros(post, response_body("post"))]
356/// async fn handle(self, ctx: &Context) {}
357/// }
358///
359/// impl Post {
360/// #[post]
361/// async fn post_with_ref_self(&self, ctx: &Context) {}
362/// }
363///
364/// #[post]
365/// async fn standalone_post_handler(ctx: &Context) {}
366/// ```
367///
368/// The macro takes no parameters and should be applied directly to async functions
369/// that accept a `&Context` parameter.
370#[proc_macro_attribute]
371pub fn post(_attr: TokenStream, item: TokenStream) -> TokenStream {
372 post_handler(item, Position::Prologue)
373}
374
375/// Restricts function execution to HTTP PUT requests only.
376///
377/// This attribute macro ensures the decorated function only executes when the incoming request
378/// uses the PUT HTTP method. Requests with other methods will be filtered out.
379///
380/// # Usage
381///
382/// ```rust
383/// use hyperlane::*;
384/// use hyperlane_macros::*;
385///
386/// #[route("/put")]
387/// struct Put;
388///
389/// impl ServerHook for Put {
390/// async fn new(_ctx: &Context) -> Self {
391/// Self
392/// }
393///
394/// #[prologue_macros(put, response_body("put"))]
395/// async fn handle(self, ctx: &Context) {}
396/// }
397///
398/// impl Put {
399/// #[put]
400/// async fn put_with_ref_self(&self, ctx: &Context) {}
401/// }
402///
403/// #[put]
404/// async fn standalone_put_handler(ctx: &Context) {}
405/// ```
406///
407/// The macro takes no parameters and should be applied directly to async functions
408/// that accept a `&Context` parameter.
409#[proc_macro_attribute]
410pub fn put(_attr: TokenStream, item: TokenStream) -> TokenStream {
411 put_handler(item, Position::Prologue)
412}
413
414/// Restricts function execution to HTTP DELETE requests only.
415///
416/// This attribute macro ensures the decorated function only executes when the incoming request
417/// uses the DELETE HTTP method. Requests with other methods will be filtered out.
418///
419/// # Usage
420///
421/// ```rust
422/// use hyperlane::*;
423/// use hyperlane_macros::*;
424///
425/// #[route("/delete")]
426/// struct Delete;
427///
428/// impl ServerHook for Delete {
429/// async fn new(_ctx: &Context) -> Self {
430/// Self
431/// }
432///
433/// #[prologue_macros(delete, response_body("delete"))]
434/// async fn handle(self, ctx: &Context) {}
435/// }
436///
437/// impl Delete {
438/// #[delete]
439/// async fn delete_with_ref_self(&self, ctx: &Context) {}
440/// }
441///
442/// #[delete]
443/// async fn standalone_delete_handler(ctx: &Context) {}
444/// ```
445///
446/// The macro takes no parameters and should be applied directly to async functions
447/// that accept a `&Context` parameter.
448#[proc_macro_attribute]
449pub fn delete(_attr: TokenStream, item: TokenStream) -> TokenStream {
450 delete_handler(item, Position::Prologue)
451}
452
453/// Restricts function execution to HTTP PATCH requests only.
454///
455/// This attribute macro ensures the decorated function only executes when the incoming request
456/// uses the PATCH HTTP method. Requests with other methods will be filtered out.
457///
458/// # Usage
459///
460/// ```rust
461/// use hyperlane::*;
462/// use hyperlane_macros::*;
463///
464/// #[route("/patch")]
465/// struct Patch;
466///
467/// impl ServerHook for Patch {
468/// async fn new(_ctx: &Context) -> Self {
469/// Self
470/// }
471///
472/// #[prologue_macros(patch, response_body("patch"))]
473/// async fn handle(self, ctx: &Context) {}
474/// }
475///
476/// impl Patch {
477/// #[patch]
478/// async fn patch_with_ref_self(&self, ctx: &Context) {}
479/// }
480///
481/// #[patch]
482/// async fn standalone_patch_handler(ctx: &Context) {}
483/// ```
484///
485/// The macro takes no parameters and should be applied directly to async functions
486/// that accept a `&Context` parameter.
487#[proc_macro_attribute]
488pub fn patch(_attr: TokenStream, item: TokenStream) -> TokenStream {
489 patch_handler(item, Position::Prologue)
490}
491
492/// Restricts function execution to HTTP HEAD requests only.
493///
494/// This attribute macro ensures the decorated function only executes when the incoming request
495/// uses the HEAD HTTP method. Requests with other methods will be filtered out.
496///
497/// # Usage
498///
499/// ```rust
500/// use hyperlane::*;
501/// use hyperlane_macros::*;
502///
503/// #[route("/head")]
504/// struct Head;
505///
506/// impl ServerHook for Head {
507/// async fn new(_ctx: &Context) -> Self {
508/// Self
509/// }
510///
511/// #[prologue_macros(head, response_body("head"))]
512/// async fn handle(self, ctx: &Context) {}
513/// }
514///
515/// impl Head {
516/// #[head]
517/// async fn head_with_ref_self(&self, ctx: &Context) {}
518/// }
519///
520/// #[head]
521/// async fn standalone_head_handler(ctx: &Context) {}
522/// ```
523///
524/// The macro takes no parameters and should be applied directly to async functions
525/// that accept a `&Context` parameter.
526#[proc_macro_attribute]
527pub fn head(_attr: TokenStream, item: TokenStream) -> TokenStream {
528 head_handler(item, Position::Prologue)
529}
530
531/// Restricts function execution to HTTP OPTIONS requests only.
532///
533/// This attribute macro ensures the decorated function only executes when the incoming request
534/// uses the OPTIONS HTTP method. Requests with other methods will be filtered out.
535///
536/// # Usage
537///
538/// ```rust
539/// use hyperlane::*;
540/// use hyperlane_macros::*;
541///
542/// #[route("/options")]
543/// struct Options;
544///
545/// impl ServerHook for Options {
546/// async fn new(_ctx: &Context) -> Self {
547/// Self
548/// }
549///
550/// #[prologue_macros(options, response_body("options"))]
551/// async fn handle(self, ctx: &Context) {}
552/// }
553///
554/// impl Options {
555/// #[options]
556/// async fn options_with_ref_self(&self, ctx: &Context) {}
557/// }
558///
559/// #[options]
560/// async fn standalone_options_handler(ctx: &Context) {}
561/// ```
562///
563/// The macro takes no parameters and should be applied directly to async functions
564/// that accept a `&Context` parameter.
565#[proc_macro_attribute]
566pub fn options(_attr: TokenStream, item: TokenStream) -> TokenStream {
567 options_handler(item, Position::Prologue)
568}
569
570/// Restricts function execution to HTTP CONNECT requests only.
571///
572/// This attribute macro ensures the decorated function only executes when the incoming request
573/// uses the CONNECT HTTP method. Requests with other methods will be filtered out.
574///
575/// # Usage
576///
577/// ```rust
578/// use hyperlane::*;
579/// use hyperlane_macros::*;
580///
581/// #[route("/connect")]
582/// struct Connect;
583///
584/// impl ServerHook for Connect {
585/// async fn new(_ctx: &Context) -> Self {
586/// Self
587/// }
588///
589/// #[prologue_macros(connect, response_body("connect"))]
590/// async fn handle(self, ctx: &Context) {}
591/// }
592///
593/// impl Connect {
594/// #[connect]
595/// async fn connect_with_ref_self(&self, ctx: &Context) {}
596/// }
597///
598/// #[connect]
599/// async fn standalone_connect_handler(ctx: &Context) {}
600/// ```
601///
602/// The macro takes no parameters and should be applied directly to async functions
603/// that accept a `&Context` parameter.
604#[proc_macro_attribute]
605pub fn connect(_attr: TokenStream, item: TokenStream) -> TokenStream {
606 connect_handler(item, Position::Prologue)
607}
608
609/// Restricts function execution to HTTP TRACE requests only.
610///
611/// This attribute macro ensures the decorated function only executes when the incoming request
612/// uses the TRACE HTTP method. Requests with other methods will be filtered out.
613///
614/// # Usage
615///
616/// ```rust
617/// use hyperlane::*;
618/// use hyperlane_macros::*;
619///
620/// #[route("/trace")]
621/// struct Trace;
622///
623/// impl ServerHook for Trace {
624/// async fn new(_ctx: &Context) -> Self {
625/// Self
626/// }
627///
628/// #[prologue_macros(trace, response_body("trace"))]
629/// async fn handle(self, ctx: &Context) {}
630/// }
631///
632/// impl Trace {
633/// #[trace]
634/// async fn trace_with_ref_self(&self, ctx: &Context) {}
635/// }
636///
637/// #[trace]
638/// async fn standalone_trace_handler(ctx: &Context) {}
639/// ```
640///
641/// The macro takes no parameters and should be applied directly to async functions
642/// that accept a `&Context` parameter.
643#[proc_macro_attribute]
644pub fn trace(_attr: TokenStream, item: TokenStream) -> TokenStream {
645 trace_handler(item, Position::Prologue)
646}
647
648/// Allows function to handle multiple HTTP methods.
649///
650/// This attribute macro configures the decorated function to execute for any of the specified
651/// HTTP methods. Methods should be provided as a comma-separated list.
652///
653/// # Usage
654///
655/// ```rust
656/// use hyperlane::*;
657/// use hyperlane_macros::*;
658///
659/// #[route("/get_post")]
660/// struct GetPost;
661///
662/// impl ServerHook for GetPost {
663/// async fn new(_ctx: &Context) -> Self {
664/// Self
665/// }
666///
667/// #[prologue_macros(
668/// http,
669/// methods(get, post),
670/// response_body("get_post")
671/// )]
672/// async fn handle(self, ctx: &Context) {}
673/// }
674///
675/// impl GetPost {
676/// #[methods(get, post)]
677/// async fn methods_with_ref_self(&self, ctx: &Context) {}
678/// }
679///
680/// #[methods(get, post)]
681/// async fn standalone_methods_handler(ctx: &Context) {}
682/// ```
683///
684/// The macro accepts a comma-separated list of HTTP method names (lowercase) and should be
685/// applied to async functions that accept a `&Context` parameter.
686#[proc_macro_attribute]
687pub fn methods(attr: TokenStream, item: TokenStream) -> TokenStream {
688 methods_macro(attr, item, Position::Prologue)
689}
690
691/// Restricts function execution to WebSocket upgrade requests only.
692///
693/// This attribute macro ensures the decorated function only executes when the incoming request
694/// is a valid WebSocket upgrade request with proper request headers and protocol negotiation.
695///
696/// # Usage
697///
698/// ```rust
699/// use hyperlane::*;
700/// use hyperlane_macros::*;
701///
702/// #[route("/ws")]
703/// struct Websocket;
704///
705/// impl ServerHook for Websocket {
706/// async fn new(_ctx: &Context) -> Self {
707/// Self
708/// }
709///
710/// #[ws]
711/// #[ws_from_stream]
712/// async fn handle(self, ctx: &Context) {
713/// let body: RequestBody = ctx.get_request_body().await;
714/// let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
715/// ctx.send_body_list_with_data(&body_list).await;
716/// }
717/// }
718///
719/// impl Websocket {
720/// #[ws]
721/// async fn ws_with_ref_self(&self, ctx: &Context) {}
722/// }
723///
724/// #[ws]
725/// async fn standalone_ws_handler(ctx: &Context) {}
726/// ```
727///
728/// The macro takes no parameters and should be applied directly to async functions
729/// that accept a `&Context` parameter.
730#[proc_macro_attribute]
731pub fn ws(_attr: TokenStream, item: TokenStream) -> TokenStream {
732 ws_macro(item, Position::Prologue)
733}
734
735/// Restricts function execution to standard HTTP requests only.
736///
737/// This attribute macro ensures the decorated function only executes for standard HTTP requests,
738/// excluding WebSocket upgrades and other protocol upgrade requests.
739///
740/// # Usage
741///
742/// ```rust
743/// use hyperlane::*;
744/// use hyperlane_macros::*;
745///
746/// #[route("/http")]
747/// struct HttpOnly;
748///
749/// impl ServerHook for HttpOnly {
750/// async fn new(_ctx: &Context) -> Self {
751/// Self
752/// }
753///
754/// #[prologue_macros(http, response_body("http"))]
755/// async fn handle(self, ctx: &Context) {}
756/// }
757///
758/// impl HttpOnly {
759/// #[http]
760/// async fn http_with_ref_self(&self, ctx: &Context) {}
761/// }
762///
763/// #[http]
764/// async fn standalone_http_handler(ctx: &Context) {}
765/// ```
766///
767/// The macro takes no parameters and should be applied directly to async functions
768/// that accept a `&Context` parameter.
769#[proc_macro_attribute]
770pub fn http(_attr: TokenStream, item: TokenStream) -> TokenStream {
771 http_macro(item, Position::Prologue)
772}
773
774/// Sets the HTTP status code for the response.
775///
776/// This attribute macro configures the HTTP status code that will be sent with the response.
777/// The status code can be provided as a numeric literal or a global constant.
778///
779/// # Usage
780///
781/// ```rust
782/// use hyperlane::*;
783/// use hyperlane_macros::*;
784///
785/// const CUSTOM_STATUS_CODE: i32 = 200;
786///
787/// #[route("/response_status_code")]
788/// struct ResponseStatusCode;
789///
790/// impl ServerHook for ResponseStatusCode {
791/// async fn new(_ctx: &Context) -> Self {
792/// Self
793/// }
794///
795/// #[response_status_code(CUSTOM_STATUS_CODE)]
796/// async fn handle(self, ctx: &Context) {}
797/// }
798///
799/// impl ResponseStatusCode {
800/// #[response_status_code(CUSTOM_STATUS_CODE)]
801/// async fn response_status_code_with_ref_self(&self, ctx: &Context) {}
802/// }
803///
804/// #[response_status_code(200)]
805/// async fn standalone_response_status_code_handler(ctx: &Context) {}
806/// ```
807///
808/// The macro accepts a numeric HTTP status code or a global constant
809/// and should be applied to async functions that accept a `&Context` parameter.
810#[proc_macro_attribute]
811pub fn response_status_code(attr: TokenStream, item: TokenStream) -> TokenStream {
812 response_status_code_macro(attr, item, Position::Prologue)
813}
814
815/// Sets the HTTP reason phrase for the response.
816///
817/// This attribute macro configures the HTTP reason phrase that accompanies the status code.
818/// The reason phrase can be provided as a string literal or a global constant.
819///
820/// # Usage
821///
822/// ```rust
823/// use hyperlane::*;
824/// use hyperlane_macros::*;
825///
826/// const CUSTOM_REASON: &str = "Accepted";
827///
828/// #[route("/response_reason")]
829/// struct ResponseReason;
830///
831/// impl ServerHook for ResponseReason {
832/// async fn new(_ctx: &Context) -> Self {
833/// Self
834/// }
835///
836/// #[response_reason_phrase(CUSTOM_REASON)]
837/// async fn handle(self, ctx: &Context) {}
838/// }
839///
840/// impl ResponseReason {
841/// #[response_reason_phrase(CUSTOM_REASON)]
842/// async fn response_reason_phrase_with_ref_self(&self, ctx: &Context) {}
843/// }
844///
845/// #[response_reason_phrase("OK")]
846/// async fn standalone_response_reason_phrase_handler(ctx: &Context) {}
847/// ```
848///
849/// The macro accepts a string literal or global constant for the reason phrase and should be
850/// applied to async functions that accept a `&Context` parameter.
851#[proc_macro_attribute]
852pub fn response_reason_phrase(attr: TokenStream, item: TokenStream) -> TokenStream {
853 response_reason_phrase_macro(attr, item, Position::Prologue)
854}
855
856/// Sets or replaces a specific HTTP response header.
857///
858/// This attribute macro configures a specific HTTP response header that will be sent with the response.
859/// Both the header name and value can be provided as string literals or global constants.
860/// Use `"key", "value"` to set a header (add to existing headers) or `"key" => "value"` to replace a header (overwrite existing).
861///
862/// # Usage
863///
864/// ```rust
865/// use hyperlane::*;
866/// use hyperlane_macros::*;
867///
868/// const CUSTOM_HEADER_NAME: &str = "X-Custom-Header";
869/// const CUSTOM_HEADER_VALUE: &str = "custom-value";
870///
871/// #[route("/response_header")]
872/// struct ResponseHeader;
873///
874/// impl ServerHook for ResponseHeader {
875/// async fn new(_ctx: &Context) -> Self {
876/// Self
877/// }
878///
879/// #[response_header(CUSTOM_HEADER_NAME => CUSTOM_HEADER_VALUE)]
880/// async fn handle(self, ctx: &Context) {}
881/// }
882///
883/// impl ResponseHeader {
884/// #[response_header(CUSTOM_HEADER_NAME => CUSTOM_HEADER_VALUE)]
885/// async fn response_header_with_ref_self(&self, ctx: &Context) {}
886/// }
887///
888/// #[route("/response_header")]
889/// struct ResponseHeaderTest;
890///
891/// impl ServerHook for ResponseHeaderTest {
892/// async fn new(_ctx: &Context) -> Self {
893/// Self
894/// }
895///
896/// #[response_body("Testing header set and replace operations")]
897/// #[response_header("X-Add-Header", "add-value")]
898/// #[response_header("X-Set-Header" => "set-value")]
899/// async fn handle(self, ctx: &Context) {}
900/// }
901///
902/// #[response_header("X-Custom" => "value")]
903/// async fn standalone_response_header_handler(ctx: &Context) {}
904/// ```
905///
906/// The macro accepts header name and header value, both can be string literals or global constants.
907/// Use `"key", "value"` for setting headers and `"key" => "value"` for replacing headers.
908/// Should be applied to async functions that accept a `&Context` parameter.
909#[proc_macro_attribute]
910pub fn response_header(attr: TokenStream, item: TokenStream) -> TokenStream {
911 response_header_macro(attr, item, Position::Prologue)
912}
913
914/// Sets the HTTP response body.
915///
916/// This attribute macro configures the HTTP response body that will be sent with the response.
917/// The body content can be provided as a string literal or a global constant.
918///
919/// # Usage
920///
921/// ```rust
922/// use hyperlane::*;
923/// use hyperlane_macros::*;
924///
925/// const RESPONSE_DATA: &str = "{\"status\": \"success\"}";
926///
927/// #[route("/response_body")]
928/// struct ResponseBody;
929///
930/// impl ServerHook for ResponseBody {
931/// async fn new(_ctx: &Context) -> Self {
932/// Self
933/// }
934///
935/// #[response_body(&RESPONSE_DATA)]
936/// async fn handle(self, ctx: &Context) {}
937/// }
938///
939/// impl ResponseBody {
940/// #[response_body(&RESPONSE_DATA)]
941/// async fn response_body_with_ref_self(&self, ctx: &Context) {}
942/// }
943///
944/// #[response_body("standalone response body")]
945/// async fn standalone_response_body_handler(ctx: &Context) {}
946/// ```
947///
948/// The macro accepts a string literal or global constant for the response body and should be
949/// applied to async functions that accept a `&Context` parameter.
950#[proc_macro_attribute]
951pub fn response_body(attr: TokenStream, item: TokenStream) -> TokenStream {
952 response_body_macro(attr, item, Position::Prologue)
953}
954
955/// Clears all response headers.
956///
957/// This attribute macro clears all response headers from the response.
958///
959/// # Usage
960///
961/// ```rust
962/// use hyperlane::*;
963/// use hyperlane_macros::*;
964///
965/// #[route("/clear_response_headers")]
966/// struct ClearResponseHeaders;
967///
968/// impl ServerHook for ClearResponseHeaders {
969/// async fn new(_ctx: &Context) -> Self {
970/// Self
971/// }
972///
973/// #[prologue_macros(
974/// clear_response_headers,
975/// filter(ctx.get_request().await.is_unknown_method()),
976/// response_body("clear_response_headers")
977/// )]
978/// async fn handle(self, ctx: &Context) {}
979/// }
980///
981/// impl ClearResponseHeaders {
982/// #[clear_response_headers]
983/// async fn clear_response_headers_with_ref_self(&self, ctx: &Context) {}
984/// }
985///
986/// #[clear_response_headers]
987/// async fn standalone_clear_response_headers_handler(ctx: &Context) {}
988/// ```
989///
990/// The macro should be applied to async functions that accept a `&Context` parameter.
991#[proc_macro_attribute]
992pub fn clear_response_headers(_attr: TokenStream, item: TokenStream) -> TokenStream {
993 clear_response_headers_macro(item, Position::Prologue)
994}
995
996/// Sets the HTTP response version.
997///
998/// This attribute macro configures the HTTP response version that will be sent with the response.
999/// The version can be provided as a variable or code block.
1000///
1001/// # Usage
1002///
1003/// ```rust
1004/// use hyperlane::*;
1005/// use hyperlane_macros::*;
1006///
1007/// #[request_middleware]
1008/// struct RequestMiddleware;
1009///
1010/// impl ServerHook for RequestMiddleware {
1011/// async fn new(_ctx: &Context) -> Self {
1012/// Self
1013/// }
1014///
1015/// #[epilogue_macros(
1016/// response_status_code(200),
1017/// response_version(HttpVersion::Http1_1),
1018/// response_header(SERVER => HYPERLANE)
1019/// )]
1020/// async fn handle(self, ctx: &Context) {}
1021/// }
1022/// ```
1023///
1024/// The macro accepts a variable or code block for the response version and should be
1025/// applied to async functions that accept a `&Context` parameter.
1026#[proc_macro_attribute]
1027pub fn response_version(attr: TokenStream, item: TokenStream) -> TokenStream {
1028 response_version_macro(attr, item, Position::Prologue)
1029}
1030
1031/// Handles aborted request scenarios.
1032///
1033/// This attribute macro configures the function to handle cases where the client has
1034/// aborted the request, providing appropriate handling for interrupted or cancelled requests.
1035///
1036/// # Usage
1037///
1038/// ```rust
1039/// use hyperlane::*;
1040/// use hyperlane_macros::*;
1041///
1042/// #[route("/aborted")]
1043/// struct Aborted;
1044///
1045/// impl ServerHook for Aborted {
1046/// async fn new(_ctx: &Context) -> Self {
1047/// Self
1048/// }
1049///
1050/// #[aborted]
1051/// async fn handle(self, ctx: &Context) {}
1052/// }
1053///
1054/// impl Aborted {
1055/// #[aborted]
1056/// async fn aborted_with_ref_self(&self, ctx: &Context) {}
1057/// }
1058///
1059/// #[aborted]
1060/// async fn standalone_aborted_handler(ctx: &Context) {}
1061/// ```
1062///
1063/// The macro takes no parameters and should be applied directly to async functions
1064/// that accept a `&Context` parameter.
1065#[proc_macro_attribute]
1066pub fn aborted(_attr: TokenStream, item: TokenStream) -> TokenStream {
1067 aborted_macro(item, Position::Prologue)
1068}
1069
1070/// Handles closed connection scenarios.
1071///
1072/// This attribute macro configures the function to handle cases where the connection
1073/// has been closed, providing appropriate handling for terminated or disconnected connections.
1074///
1075/// # Usage
1076///
1077/// ```rust
1078/// use hyperlane::*;
1079/// use hyperlane_macros::*;
1080///
1081/// #[route("/closed")]
1082/// struct ClosedTest;
1083///
1084/// impl ServerHook for ClosedTest {
1085/// async fn new(_ctx: &Context) -> Self {
1086/// Self
1087/// }
1088///
1089/// #[closed]
1090/// async fn handle(self, ctx: &Context) {}
1091/// }
1092///
1093/// impl ClosedTest {
1094/// #[closed]
1095/// async fn closed_with_ref_self(&self, ctx: &Context) {}
1096/// }
1097///
1098/// #[closed]
1099/// async fn standalone_closed_handler(ctx: &Context) {}
1100/// ```
1101///
1102/// The macro takes no parameters and should be applied directly to async functions
1103/// that accept a `&Context` parameter.
1104#[proc_macro_attribute]
1105pub fn closed(_attr: TokenStream, item: TokenStream) -> TokenStream {
1106 closed_macro(item, Position::Prologue)
1107}
1108
1109/// Restricts function execution to HTTP/2 Cleartext (h2c) requests only.
1110///
1111/// This attribute macro ensures the decorated function only executes for HTTP/2 cleartext
1112/// requests that use the h2c upgrade mechanism.
1113///
1114/// # Usage
1115///
1116/// ```rust
1117/// use hyperlane::*;
1118/// use hyperlane_macros::*;
1119///
1120/// #[route("/h2c")]
1121/// struct H2c;
1122///
1123/// impl ServerHook for H2c {
1124/// async fn new(_ctx: &Context) -> Self {
1125/// Self
1126/// }
1127///
1128/// #[prologue_macros(h2c, response_body("h2c"))]
1129/// async fn handle(self, ctx: &Context) {}
1130/// }
1131///
1132/// impl H2c {
1133/// #[h2c]
1134/// async fn h2c_with_ref_self(&self, ctx: &Context) {}
1135/// }
1136///
1137/// #[h2c]
1138/// async fn standalone_h2c_handler(ctx: &Context) {}
1139/// ```
1140///
1141/// The macro takes no parameters and should be applied directly to async functions
1142/// that accept a `&Context` parameter.
1143#[proc_macro_attribute]
1144pub fn h2c(_attr: TokenStream, item: TokenStream) -> TokenStream {
1145 h2c_macro(item, Position::Prologue)
1146}
1147
1148/// Restricts function execution to HTTP/0.9 requests only.
1149///
1150/// This attribute macro ensures the decorated function only executes for HTTP/0.9
1151/// protocol requests, the earliest version of the HTTP protocol.
1152///
1153/// # Usage
1154///
1155/// ```rust
1156/// use hyperlane::*;
1157/// use hyperlane_macros::*;
1158///
1159/// #[route("/http0_9")]
1160/// struct Http09;
1161///
1162/// impl ServerHook for Http09 {
1163/// async fn new(_ctx: &Context) -> Self {
1164/// Self
1165/// }
1166///
1167/// #[prologue_macros(http0_9, response_body("http0_9"))]
1168/// async fn handle(self, ctx: &Context) {}
1169/// }
1170///
1171/// impl Http09 {
1172/// #[http0_9]
1173/// async fn http0_9_with_ref_self(&self, ctx: &Context) {}
1174/// }
1175///
1176/// #[http0_9]
1177/// async fn standalone_http0_9_handler(ctx: &Context) {}
1178/// ```
1179///
1180/// The macro takes no parameters and should be applied directly to async functions
1181/// that accept a `&Context` parameter.
1182#[proc_macro_attribute]
1183pub fn http0_9(_attr: TokenStream, item: TokenStream) -> TokenStream {
1184 http0_9_macro(item, Position::Prologue)
1185}
1186
1187/// Restricts function execution to HTTP/1.0 requests only.
1188///
1189/// This attribute macro ensures the decorated function only executes for HTTP/1.0
1190/// protocol requests.
1191///
1192/// # Usage
1193///
1194/// ```rust
1195/// use hyperlane::*;
1196/// use hyperlane_macros::*;
1197///
1198/// #[route("/http1_0")]
1199/// struct Http10;
1200///
1201/// impl ServerHook for Http10 {
1202/// async fn new(_ctx: &Context) -> Self {
1203/// Self
1204/// }
1205///
1206/// #[prologue_macros(http1_0, response_body("http1_0"))]
1207/// async fn handle(self, ctx: &Context) {}
1208/// }
1209///
1210/// impl Http10 {
1211/// #[http1_0]
1212/// async fn http1_0_with_ref_self(&self, ctx: &Context) {}
1213/// }
1214///
1215/// #[http1_0]
1216/// async fn standalone_http1_0_handler(ctx: &Context) {}
1217/// ```
1218///
1219/// The macro takes no parameters and should be applied directly to async functions
1220/// that accept a `&Context` parameter.
1221#[proc_macro_attribute]
1222pub fn http1_0(_attr: TokenStream, item: TokenStream) -> TokenStream {
1223 http1_0_macro(item, Position::Prologue)
1224}
1225
1226/// Restricts function execution to HTTP/1.1 requests only.
1227///
1228/// This attribute macro ensures the decorated function only executes for HTTP/1.1
1229/// protocol requests.
1230///
1231/// # Usage
1232///
1233/// ```rust
1234/// use hyperlane::*;
1235/// use hyperlane_macros::*;
1236///
1237/// #[route("/http1_1")]
1238/// struct Http11;
1239///
1240/// impl ServerHook for Http11 {
1241/// async fn new(_ctx: &Context) -> Self {
1242/// Self
1243/// }
1244///
1245/// #[prologue_macros(http1_1, response_body("http1_1"))]
1246/// async fn handle(self, ctx: &Context) {}
1247/// }
1248///
1249/// impl Http11 {
1250/// #[http1_1]
1251/// async fn http1_1_with_ref_self(&self, ctx: &Context) {}
1252/// }
1253///
1254/// #[http1_1]
1255/// async fn standalone_http1_1_handler(ctx: &Context) {}
1256/// ```
1257///
1258/// The macro takes no parameters and should be applied directly to async functions
1259/// that accept a `&Context` parameter.
1260#[proc_macro_attribute]
1261pub fn http1_1(_attr: TokenStream, item: TokenStream) -> TokenStream {
1262 http1_1_macro(item, Position::Prologue)
1263}
1264
1265/// Restricts function execution to HTTP/1.1 or higher protocol versions.
1266///
1267/// This attribute macro ensures the decorated function only executes for HTTP/1.1
1268/// or newer protocol versions, including HTTP/2, HTTP/3, and future versions.
1269///
1270/// # Usage
1271///
1272/// ```rust
1273/// use hyperlane::*;
1274/// use hyperlane_macros::*;
1275///
1276/// #[route("/http1_1_or_higher")]
1277/// struct Http11OrHigher;
1278///
1279/// impl ServerHook for Http11OrHigher {
1280/// async fn new(_ctx: &Context) -> Self {
1281/// Self
1282/// }
1283///
1284/// #[prologue_macros(http1_1_or_higher, response_body("http1_1_or_higher"))]
1285/// async fn handle(self, ctx: &Context) {}
1286/// }
1287///
1288/// impl Http11OrHigher {
1289/// #[http1_1_or_higher]
1290/// async fn http1_1_or_higher_with_ref_self(&self, ctx: &Context) {}
1291/// }
1292///
1293/// #[http1_1_or_higher]
1294/// async fn standalone_http1_1_or_higher_handler(ctx: &Context) {}
1295/// ```
1296///
1297/// The macro takes no parameters and should be applied directly to async functions
1298/// that accept a `&Context` parameter.
1299#[proc_macro_attribute]
1300pub fn http1_1_or_higher(_attr: TokenStream, item: TokenStream) -> TokenStream {
1301 http1_1_or_higher_macro(item, Position::Prologue)
1302}
1303
1304/// Restricts function execution to HTTP/2 requests only.
1305///
1306/// This attribute macro ensures the decorated function only executes for HTTP/2
1307/// protocol requests.
1308///
1309/// # Usage
1310///
1311/// ```rust
1312/// use hyperlane::*;
1313/// use hyperlane_macros::*;
1314///
1315/// #[route("/http2")]
1316/// struct Http2;
1317///
1318/// impl ServerHook for Http2 {
1319/// async fn new(_ctx: &Context) -> Self {
1320/// Self
1321/// }
1322///
1323/// #[prologue_macros(http2, response_body("http2"))]
1324/// async fn handle(self, ctx: &Context) {}
1325/// }
1326///
1327/// impl Http2 {
1328/// #[http2]
1329/// async fn http2_with_ref_self(&self, ctx: &Context) {}
1330/// }
1331///
1332/// #[http2]
1333/// async fn standalone_http2_handler(ctx: &Context) {}
1334/// ```
1335///
1336/// The macro takes no parameters and should be applied directly to async functions
1337/// that accept a `&Context` parameter.
1338#[proc_macro_attribute]
1339pub fn http2(_attr: TokenStream, item: TokenStream) -> TokenStream {
1340 http2_macro(item, Position::Prologue)
1341}
1342
1343/// Restricts function execution to HTTP/3 requests only.
1344///
1345/// This attribute macro ensures the decorated function only executes for HTTP/3
1346/// protocol requests, the latest version of the HTTP protocol.
1347///
1348/// # Usage
1349///
1350/// ```rust
1351/// use hyperlane::*;
1352/// use hyperlane_macros::*;
1353///
1354/// #[route("/http3")]
1355/// struct Http3;
1356///
1357/// impl ServerHook for Http3 {
1358/// async fn new(_ctx: &Context) -> Self {
1359/// Self
1360/// }
1361///
1362/// #[prologue_macros(http3, response_body("http3"))]
1363/// async fn handle(self, ctx: &Context) {}
1364/// }
1365///
1366/// impl Http3 {
1367/// #[http3]
1368/// async fn http3_with_ref_self(&self, ctx: &Context) {}
1369/// }
1370///
1371/// #[http3]
1372/// async fn standalone_http3_handler(ctx: &Context) {}
1373/// ```
1374///
1375/// The macro takes no parameters and should be applied directly to async functions
1376/// that accept a `&Context` parameter.
1377#[proc_macro_attribute]
1378pub fn http3(_attr: TokenStream, item: TokenStream) -> TokenStream {
1379 http3_macro(item, Position::Prologue)
1380}
1381
1382/// Restricts function execution to TLS-encrypted requests only.
1383///
1384/// This attribute macro ensures the decorated function only executes for requests
1385/// that use TLS/SSL encryption on the connection.
1386///
1387/// # Usage
1388///
1389/// ```rust
1390/// use hyperlane::*;
1391/// use hyperlane_macros::*;
1392///
1393/// #[route("/tls")]
1394/// struct Tls;
1395///
1396/// impl ServerHook for Tls {
1397/// async fn new(_ctx: &Context) -> Self {
1398/// Self
1399/// }
1400///
1401/// #[prologue_macros(tls, response_body("tls"))]
1402/// async fn handle(self, ctx: &Context) {}
1403/// }
1404///
1405/// impl Tls {
1406/// #[tls]
1407/// async fn tls_with_ref_self(&self, ctx: &Context) {}
1408/// }
1409///
1410/// #[tls]
1411/// async fn standalone_tls_handler(ctx: &Context) {}
1412/// ```
1413///
1414/// The macro takes no parameters and should be applied directly to async functions
1415/// that accept a `&Context` parameter.
1416#[proc_macro_attribute]
1417pub fn tls(_attr: TokenStream, item: TokenStream) -> TokenStream {
1418 tls_macro(item, Position::Prologue)
1419}
1420
1421/// Filters requests based on a boolean condition.
1422///
1423/// The function continues execution only if the provided code block returns `true`.
1424///
1425/// # Usage
1426///
1427/// ```rust
1428/// use hyperlane::*;
1429/// use hyperlane_macros::*;
1430///
1431/// #[route("/unknown_method")]
1432/// struct UnknownMethod;
1433///
1434/// impl ServerHook for UnknownMethod {
1435/// async fn new(_ctx: &Context) -> Self {
1436/// Self
1437/// }
1438///
1439/// #[prologue_macros(
1440/// filter(ctx.get_request().await.is_unknown_method()),
1441/// response_body("unknown_method")
1442/// )]
1443/// async fn handle(self, ctx: &Context) {}
1444/// }
1445/// ```
1446#[proc_macro_attribute]
1447pub fn filter(attr: TokenStream, item: TokenStream) -> TokenStream {
1448 filter_macro(attr, item, Position::Prologue)
1449}
1450
1451/// Rejects requests based on a boolean condition.
1452///
1453/// The function continues execution only if the provided code block returns `false`.
1454///
1455/// # Usage
1456///
1457/// ```rust
1458/// use hyperlane::*;
1459/// use hyperlane_macros::*;
1460///
1461/// #[response_middleware(2)]
1462/// struct ResponseMiddleware2;
1463///
1464/// impl ServerHook for ResponseMiddleware2 {
1465/// async fn new(_ctx: &Context) -> Self {
1466/// Self
1467/// }
1468///
1469/// #[prologue_macros(
1470/// reject(ctx.get_request().await.is_ws())
1471/// )]
1472/// async fn handle(self, ctx: &Context) {}
1473/// }
1474/// ```
1475#[proc_macro_attribute]
1476pub fn reject(attr: TokenStream, item: TokenStream) -> TokenStream {
1477 reject_macro(attr, item, Position::Prologue)
1478}
1479
1480/// Restricts function execution to requests with a specific host.
1481///
1482/// This attribute macro ensures the decorated function only executes when the incoming request
1483/// has a host header that matches the specified value. Requests with different or missing host headers will be filtered out.
1484///
1485/// # Usage
1486///
1487/// ```rust
1488/// use hyperlane::*;
1489/// use hyperlane_macros::*;
1490///
1491/// #[route("/host")]
1492/// struct Host;
1493///
1494/// impl ServerHook for Host {
1495/// async fn new(_ctx: &Context) -> Self {
1496/// Self
1497/// }
1498///
1499/// #[host("localhost")]
1500/// #[prologue_macros(response_body("host string literal: localhost"), send)]
1501/// async fn handle(self, ctx: &Context) {}
1502/// }
1503///
1504/// impl Host {
1505/// #[host("localhost")]
1506/// async fn host_with_ref_self(&self, ctx: &Context) {}
1507/// }
1508///
1509/// #[host("localhost")]
1510/// async fn standalone_host_handler(ctx: &Context) {}
1511/// ```
1512///
1513/// The macro accepts a string literal specifying the expected host value and should be
1514/// applied to async functions that accept a `&Context` parameter.
1515#[proc_macro_attribute]
1516pub fn host(attr: TokenStream, item: TokenStream) -> TokenStream {
1517 host_macro(attr, item, Position::Prologue)
1518}
1519
1520/// Reject requests that have no host header.
1521///
1522/// This attribute macro ensures the decorated function only executes when the incoming request
1523/// has a host header present. Requests without a host header will be filtered out.
1524///
1525/// # Usage
1526///
1527/// ```rust
1528/// use hyperlane::*;
1529/// use hyperlane_macros::*;
1530///
1531/// #[route("/reject_host")]
1532/// struct RejectHost;
1533///
1534/// impl ServerHook for RejectHost {
1535/// async fn new(_ctx: &Context) -> Self {
1536/// Self
1537/// }
1538///
1539/// #[prologue_macros(
1540/// reject_host("filter.localhost"),
1541/// response_body("host filter string literal")
1542/// )]
1543/// async fn handle(self, ctx: &Context) {}
1544/// }
1545///
1546/// impl RejectHost {
1547/// #[reject_host("filter.localhost")]
1548/// async fn reject_host_with_ref_self(&self, ctx: &Context) {}
1549/// }
1550///
1551/// #[reject_host("filter.localhost")]
1552/// async fn standalone_reject_host_handler(ctx: &Context) {}
1553/// ```
1554///
1555/// The macro takes no parameters and should be applied directly to async functions
1556/// that accept a `&Context` parameter.
1557#[proc_macro_attribute]
1558pub fn reject_host(attr: TokenStream, item: TokenStream) -> TokenStream {
1559 reject_host_macro(attr, item, Position::Prologue)
1560}
1561
1562/// Restricts function execution to requests with a specific referer.
1563///
1564/// This attribute macro ensures the decorated function only executes when the incoming request
1565/// has a referer header that matches the specified value. Requests with different or missing referer headers will be filtered out.
1566///
1567/// # Usage
1568///
1569/// ```rust
1570/// use hyperlane::*;
1571/// use hyperlane_macros::*;
1572///
1573/// #[route("/referer")]
1574/// struct Referer;
1575///
1576/// impl ServerHook for Referer {
1577/// async fn new(_ctx: &Context) -> Self {
1578/// Self
1579/// }
1580///
1581/// #[prologue_macros(
1582/// referer("http://localhost"),
1583/// response_body("referer string literal: http://localhost")
1584/// )]
1585/// async fn handle(self, ctx: &Context) {}
1586/// }
1587///
1588/// impl Referer {
1589/// #[referer("http://localhost")]
1590/// async fn referer_with_ref_self(&self, ctx: &Context) {}
1591/// }
1592///
1593/// #[referer("http://localhost")]
1594/// async fn standalone_referer_handler(ctx: &Context) {}
1595/// ```
1596///
1597/// The macro accepts a string literal specifying the expected referer value and should be
1598/// applied to async functions that accept a `&Context` parameter.
1599#[proc_macro_attribute]
1600pub fn referer(attr: TokenStream, item: TokenStream) -> TokenStream {
1601 referer_macro(attr, item, Position::Prologue)
1602}
1603
1604/// Reject requests that have a specific referer header.
1605///
1606/// This attribute macro ensures the decorated function only executes when the incoming request
1607/// does not have a referer header that matches the specified value. Requests with the matching referer header will be filtered out.
1608///
1609/// # Usage
1610///
1611/// ```rust
1612/// use hyperlane::*;
1613/// use hyperlane_macros::*;
1614///
1615/// #[route("/reject_referer")]
1616/// struct RejectReferer;
1617///
1618/// impl ServerHook for RejectReferer {
1619/// async fn new(_ctx: &Context) -> Self {
1620/// Self
1621/// }
1622///
1623/// #[prologue_macros(
1624/// reject_referer("http://localhost"),
1625/// response_body("referer filter string literal")
1626/// )]
1627/// async fn handle(self, ctx: &Context) {}
1628/// }
1629///
1630/// impl RejectReferer {
1631/// #[reject_referer("http://localhost")]
1632/// async fn reject_referer_with_ref_self(&self, ctx: &Context) {}
1633/// }
1634///
1635/// #[reject_referer("http://localhost")]
1636/// async fn standalone_reject_referer_handler(ctx: &Context) {}
1637/// ```
1638///
1639/// The macro accepts a string literal specifying the referer value to filter out and should be
1640/// applied to async functions that accept a `&Context` parameter.
1641#[proc_macro_attribute]
1642pub fn reject_referer(attr: TokenStream, item: TokenStream) -> TokenStream {
1643 reject_referer_macro(attr, item, Position::Prologue)
1644}
1645
1646/// Executes multiple specified functions before the main handler function.
1647///
1648/// This attribute macro configures multiple pre-execution hooks that run before the main function logic.
1649/// The specified hook functions will be called in the order provided, followed by the main function execution.
1650///
1651/// # Usage
1652///
1653/// ```rust
1654/// use hyperlane::*;
1655/// use hyperlane_macros::*;
1656///
1657/// struct PrologueHooks;
1658///
1659/// impl ServerHook for PrologueHooks {
1660/// async fn new(_ctx: &Context) -> Self {
1661/// Self
1662/// }
1663///
1664/// #[get]
1665/// #[http]
1666/// async fn handle(self, _ctx: &Context) {}
1667/// }
1668///
1669/// async fn prologue_hooks_fn(ctx: &Context) {
1670/// let hook = PrologueHooks::new(&ctx).await;
1671/// hook.handle(&ctx).await;
1672/// }
1673///
1674/// #[route("/hook")]
1675/// struct Hook;
1676///
1677/// impl ServerHook for Hook {
1678/// async fn new(_ctx: &Context) -> Self {
1679/// Self
1680/// }
1681///
1682/// #[prologue_hooks(prologue_hooks_fn)]
1683/// #[response_body("Testing hook macro")]
1684/// async fn handle(self, ctx: &Context) {}
1685/// }
1686/// ```
1687///
1688/// The macro accepts a comma-separated list of function names as parameters. All hook functions
1689/// and the main function must accept a `Context` parameter. Avoid combining this macro with other
1690/// macros on the same function to prevent macro expansion conflicts.
1691///
1692/// # Advanced Usage with Method Expressions
1693///
1694/// ```rust
1695/// use hyperlane::*;
1696/// use hyperlane_macros::*;
1697///
1698/// #[route("/hooks_expression")]
1699/// struct HooksExpression;
1700///
1701/// impl ServerHook for HooksExpression {
1702/// async fn new(_ctx: &Context) -> Self {
1703/// Self
1704/// }
1705///
1706/// #[get]
1707/// #[prologue_hooks(HooksExpression::new_hook, HooksExpression::method_hook)]
1708/// #[response_body("hooks expression test")]
1709/// async fn handle(self, ctx: &Context) {}
1710/// }
1711///
1712/// impl HooksExpression {
1713/// async fn new_hook(_ctx: &Context) {}
1714///
1715/// async fn method_hook(_ctx: &Context) {}
1716/// }
1717/// ```
1718#[proc_macro_attribute]
1719pub fn prologue_hooks(attr: TokenStream, item: TokenStream) -> TokenStream {
1720 prologue_hooks_macro(attr, item, Position::Prologue)
1721}
1722
1723/// Executes multiple specified functions after the main handler function.
1724///
1725/// This attribute macro configures multiple post-execution hooks that run after the main function logic.
1726/// The main function will execute first, followed by the specified hook functions in the order provided.
1727///
1728/// # Usage
1729///
1730/// ```rust
1731/// use hyperlane::*;
1732/// use hyperlane_macros::*;
1733///
1734/// struct EpilogueHooks;
1735///
1736/// impl ServerHook for EpilogueHooks {
1737/// async fn new(_ctx: &Context) -> Self {
1738/// Self
1739/// }
1740///
1741/// #[response_status_code(200)]
1742/// async fn handle(self, ctx: &Context) {}
1743/// }
1744///
1745/// async fn epilogue_hooks_fn(ctx: &Context) {
1746/// let hook = EpilogueHooks::new(&ctx).await;
1747/// hook.handle(&ctx).await;
1748/// }
1749///
1750/// #[route("/hook")]
1751/// struct Hook;
1752///
1753/// impl ServerHook for Hook {
1754/// async fn new(_ctx: &Context) -> Self {
1755/// Self
1756/// }
1757///
1758/// #[epilogue_hooks(epilogue_hooks_fn)]
1759/// #[response_body("Testing hook macro")]
1760/// async fn handle(self, ctx: &Context) {}
1761/// }
1762///
1763/// ```
1764///
1765/// The macro accepts a comma-separated list of function names as parameters. All hook functions
1766/// and the main function must accept a `Context` parameter. Avoid combining this macro with other
1767/// macros on the same function to prevent macro expansion conflicts.
1768///
1769/// # Advanced Usage with Method Expressions
1770///
1771/// ```rust
1772/// use hyperlane::*;
1773/// use hyperlane_macros::*;
1774///
1775/// #[route("/hooks_expression")]
1776/// struct HooksExpression;
1777///
1778/// impl ServerHook for HooksExpression {
1779/// async fn new(_ctx: &Context) -> Self {
1780/// Self
1781/// }
1782///
1783/// #[get]
1784/// #[epilogue_hooks(HooksExpression::new_hook, HooksExpression::method_hook)]
1785/// #[response_body("hooks expression test")]
1786/// async fn handle(self, ctx: &Context) {}
1787/// }
1788///
1789/// impl HooksExpression {
1790/// async fn new_hook(_ctx: &Context) {}
1791///
1792/// async fn method_hook(_ctx: &Context) {}
1793/// }
1794/// ```
1795#[proc_macro_attribute]
1796pub fn epilogue_hooks(attr: TokenStream, item: TokenStream) -> TokenStream {
1797 epilogue_hooks_macro(attr, item, Position::Epilogue)
1798}
1799
1800/// Extracts the raw request body into a specified variable.
1801///
1802/// This attribute macro extracts the raw request body content into a variable
1803/// with the fixed type `RequestBody`. The body content is not parsed or deserialized.
1804///
1805/// # Usage
1806///
1807/// ```rust
1808/// use hyperlane::*;
1809/// use hyperlane_macros::*;
1810///
1811/// #[route("/request_body")]
1812/// struct RequestBodyRoute;
1813///
1814/// impl ServerHook for RequestBodyRoute {
1815/// async fn new(_ctx: &Context) -> Self {
1816/// Self
1817/// }
1818///
1819/// #[response_body(&format!("raw body: {raw_body:?}"))]
1820/// #[request_body(raw_body)]
1821/// async fn handle(self, ctx: &Context) {}
1822/// }
1823///
1824/// impl RequestBodyRoute {
1825/// #[request_body(raw_body)]
1826/// async fn request_body_with_ref_self(&self, ctx: &Context) {}
1827/// }
1828///
1829/// #[request_body(raw_body)]
1830/// async fn standalone_request_body_handler(ctx: &Context) {}
1831/// ```
1832///
1833/// # Multi-Parameter Usage
1834///
1835/// ```rust
1836/// use hyperlane::*;
1837/// use hyperlane_macros::*;
1838///
1839/// #[route("/multi_body")]
1840/// struct MultiBody;
1841///
1842/// impl ServerHook for MultiBody {
1843/// async fn new(_ctx: &Context) -> Self {
1844/// Self
1845/// }
1846///
1847/// #[response_body(&format!("bodies: {body1:?}, {body2:?}"))]
1848/// #[request_body(body1, body2)]
1849/// async fn handle(self, ctx: &Context) {}
1850/// }
1851/// ```
1852///
1853/// The macro accepts one or more variable names separated by commas.
1854/// Each variable will be available in the function scope as a `RequestBody` type.
1855#[proc_macro_attribute]
1856pub fn request_body(attr: TokenStream, item: TokenStream) -> TokenStream {
1857 request_body_macro(attr, item, Position::Prologue)
1858}
1859
1860/// Parses the request body as JSON into a specified variable and type with panic on parsing failure.
1861///
1862/// This attribute macro extracts and deserializes the request body content as JSON into a variable
1863/// with the specified type. The body content is parsed as JSON using serde.
1864/// If the request body does not exist or JSON parsing fails, the function will panic with an error message.
1865///
1866/// # Usage
1867///
1868/// ```rust
1869/// use hyperlane::*;
1870/// use hyperlane_macros::*;
1871/// use serde::{Deserialize, Serialize};
1872///
1873/// #[derive(Debug, Serialize, Deserialize, Clone)]
1874/// struct TestData {
1875/// name: String,
1876/// age: u32,
1877/// }
1878///
1879/// #[route("/request_body_json_result")]
1880/// struct RequestBodyJson;
1881///
1882/// impl ServerHook for RequestBodyJson {
1883/// async fn new(_ctx: &Context) -> Self {
1884/// Self
1885/// }
1886///
1887/// #[response_body(&format!("request data: {request_data_result:?}"))]
1888/// #[request_body_json_result(request_data_result: TestData)]
1889/// async fn handle(self, ctx: &Context) {}
1890/// }
1891///
1892/// impl RequestBodyJson {
1893/// #[request_body_json_result(request_data_result: TestData)]
1894/// async fn request_body_json_with_ref_self(&self, ctx: &Context) {}
1895/// }
1896///
1897/// #[request_body_json_result(request_data_result: TestData)]
1898/// async fn standalone_request_body_json_handler(ctx: &Context) {}
1899/// ```
1900///
1901/// # Multi-Parameter Usage
1902///
1903/// ```rust
1904/// use hyperlane::*;
1905/// use hyperlane_macros::*;
1906/// use serde::{Deserialize, Serialize};
1907///
1908/// #[derive(Debug, Serialize, Deserialize, Clone)]
1909/// struct User {
1910/// name: String,
1911/// }
1912///
1913/// #[derive(Debug, Serialize, Deserialize, Clone)]
1914/// struct Config {
1915/// debug: bool,
1916/// }
1917///
1918/// #[route("/request_body_json_result")]
1919/// struct TestData;
1920///
1921/// impl ServerHook for TestData {
1922/// async fn new(_ctx: &Context) -> Self {
1923/// Self
1924/// }
1925///
1926/// #[response_body(&format!("user: {user:?}, config: {config:?}"))]
1927/// #[request_body_json_result(user: User, config: Config)]
1928/// async fn handle(self, ctx: &Context) {}
1929/// }
1930/// ```
1931///
1932/// The macro accepts one or more `variable_name: Type` pairs separated by commas.
1933/// Each variable will be available in the function scope as a `Result<Type, serde_json::Error>`.
1934#[proc_macro_attribute]
1935pub fn request_body_json_result(attr: TokenStream, item: TokenStream) -> TokenStream {
1936 request_body_json_result_macro(attr, item, Position::Prologue)
1937}
1938
1939/// Parses the request body as JSON into a specified variable and type with panic on parsing failure.
1940///
1941/// This attribute macro extracts and deserializes the request body content as JSON into a variable
1942/// with the specified type. The body content is parsed as JSON using serde.
1943/// If the request body does not exist or JSON parsing fails, the function will panic with an error message.
1944///
1945/// # Usage
1946///
1947/// ```rust
1948/// use hyperlane::*;
1949/// use hyperlane_macros::*;
1950/// use serde::{Deserialize, Serialize};
1951///
1952/// #[derive(Debug, Serialize, Deserialize, Clone)]
1953/// struct TestData {
1954/// name: String,
1955/// age: u32,
1956/// }
1957///
1958/// #[route("/request_body_json")]
1959/// struct RequestBodyJson;
1960///
1961/// impl ServerHook for RequestBodyJson {
1962/// async fn new(_ctx: &Context) -> Self {
1963/// Self
1964/// }
1965///
1966/// #[response_body(&format!("request data: {request_data_result:?}"))]
1967/// #[request_body_json(request_data_result: TestData)]
1968/// async fn handle(self, ctx: &Context) {}
1969/// }
1970///
1971/// impl RequestBodyJson {
1972/// #[request_body_json(request_data_result: TestData)]
1973/// async fn request_body_json_with_ref_self(&self, ctx: &Context) {}
1974/// }
1975///
1976/// #[request_body_json(request_data_result: TestData)]
1977/// async fn standalone_request_body_json_handler(ctx: &Context) {}
1978/// ```
1979///
1980/// # Multi-Parameter Usage
1981///
1982/// ```rust
1983/// use hyperlane::*;
1984/// use hyperlane_macros::*;
1985/// use serde::{Deserialize, Serialize};
1986///
1987/// #[derive(Debug, Serialize, Deserialize, Clone)]
1988/// struct User {
1989/// name: String,
1990/// }
1991///
1992/// #[derive(Debug, Serialize, Deserialize, Clone)]
1993/// struct Config {
1994/// debug: bool,
1995/// }
1996///
1997/// #[route("/request_body_json")]
1998/// struct TestData;
1999///
2000/// impl ServerHook for TestData {
2001/// async fn new(_ctx: &Context) -> Self {
2002/// Self
2003/// }
2004///
2005/// #[response_body(&format!("user: {user:?}, config: {config:?}"))]
2006/// #[request_body_json(user: User, config: Config)]
2007/// async fn handle(self, ctx: &Context) {}
2008/// }
2009/// ```
2010///
2011/// The macro accepts one or more `variable_name: Type` pairs separated by commas.
2012/// Each variable will be available in the function scope as a `Result<Type, serde_json::Error>`.
2013///
2014/// # Panics
2015///
2016/// This macro will panic if the request body does not exist or JSON parsing fails.
2017#[proc_macro_attribute]
2018pub fn request_body_json(attr: TokenStream, item: TokenStream) -> TokenStream {
2019 request_body_json_macro(attr, item, Position::Prologue)
2020}
2021
2022/// Extracts a specific attribute value into a variable wrapped in Option type.
2023///
2024/// This attribute macro retrieves a specific attribute by key and makes it available
2025/// as a typed Option variable from the request context. The extracted value is wrapped
2026/// in an Option type to safely handle cases where the attribute may not exist.
2027///
2028/// # Usage
2029///
2030/// ```rust
2031/// use hyperlane::*;
2032/// use hyperlane_macros::*;
2033/// use serde::{Deserialize, Serialize};
2034///
2035/// const TEST_ATTRIBUTE_KEY: &str = "test_attribute_key";
2036///
2037/// #[derive(Debug, Serialize, Deserialize, Clone)]
2038/// struct TestData {
2039/// name: String,
2040/// age: u32,
2041/// }
2042///
2043/// #[route("/attribute_option")]
2044/// struct Attribute;
2045///
2046/// impl ServerHook for Attribute {
2047/// async fn new(_ctx: &Context) -> Self {
2048/// Self
2049/// }
2050///
2051/// #[response_body(&format!("request attribute: {request_attribute_option:?}"))]
2052/// #[attribute_option(TEST_ATTRIBUTE_KEY => request_attribute_option: TestData)]
2053/// async fn handle(self, ctx: &Context) {}
2054/// }
2055///
2056/// impl Attribute {
2057/// #[attribute_option(TEST_ATTRIBUTE_KEY => request_attribute_option: TestData)]
2058/// async fn attribute_with_ref_self(&self, ctx: &Context) {}
2059/// }
2060///
2061/// #[attribute_option(TEST_ATTRIBUTE_KEY => request_attribute_option: TestData)]
2062/// async fn standalone_attribute_handler(ctx: &Context) {}
2063/// ```
2064///
2065/// The macro accepts a key-to-variable mapping in the format `key => variable_name: Type`.
2066/// The variable will be available as an `Option<Type>` in the function scope.
2067///
2068/// # Multi-Parameter Usage
2069///
2070/// ```rust
2071/// use hyperlane::*;
2072/// use hyperlane_macros::*;
2073///
2074/// #[route("/attribute_option")]
2075/// struct MultiAttr;
2076///
2077/// impl ServerHook for MultiAttr {
2078/// async fn new(_ctx: &Context) -> Self {
2079/// Self
2080/// }
2081///
2082/// #[response_body(&format!("attrs: {attr1:?}, {attr2:?}"))]
2083/// #[attribute_option("key1" => attr1: String, "key2" => attr2: i32)]
2084/// async fn handle(self, ctx: &Context) {}
2085/// }
2086/// ```
2087///
2088/// The macro accepts multiple `key => variable_name: Type` tuples separated by commas.
2089#[proc_macro_attribute]
2090pub fn attribute_option(attr: TokenStream, item: TokenStream) -> TokenStream {
2091 attribute_option_macro(attr, item, Position::Prologue)
2092}
2093
2094/// Extracts a specific attribute value into a variable with panic on missing value.
2095///
2096/// This attribute macro retrieves a specific attribute by key and makes it available
2097/// as a typed variable from the request context. If the attribute does not exist,
2098/// the function will panic with an error message indicating the missing attribute.
2099///
2100/// # Usage
2101///
2102/// ```rust
2103/// use hyperlane::*;
2104/// use hyperlane_macros::*;
2105/// use serde::{Deserialize, Serialize};
2106///
2107/// const TEST_ATTRIBUTE_KEY: &str = "test_attribute_key";
2108///
2109/// #[derive(Debug, Serialize, Deserialize, Clone)]
2110/// struct TestData {
2111/// name: String,
2112/// age: u32,
2113/// }
2114///
2115/// #[route("/attribute")]
2116/// struct Attribute;
2117///
2118/// impl ServerHook for Attribute {
2119/// async fn new(_ctx: &Context) -> Self {
2120/// Self
2121/// }
2122///
2123/// #[response_body(&format!("request attribute: {request_attribute:?}"))]
2124/// #[attribute(TEST_ATTRIBUTE_KEY => request_attribute: TestData)]
2125/// async fn handle(self, ctx: &Context) {}
2126/// }
2127///
2128/// impl Attribute {
2129/// #[attribute(TEST_ATTRIBUTE_KEY => request_attribute: TestData)]
2130/// async fn attribute_with_ref_self(&self, ctx: &Context) {}
2131/// }
2132///
2133/// #[attribute(TEST_ATTRIBUTE_KEY => request_attribute: TestData)]
2134/// async fn standalone_attribute_handler(ctx: &Context) {}
2135/// ```
2136///
2137/// The macro accepts a key-to-variable mapping in the format `key => variable_name: Type`.
2138/// The variable will be available as an `Type` in the function scope.
2139///
2140/// # Multi-Parameter Usage
2141///
2142/// ```rust
2143/// use hyperlane::*;
2144/// use hyperlane_macros::*;
2145///
2146/// #[route("/attribute")]
2147/// struct MultiAttr;
2148///
2149/// impl ServerHook for MultiAttr {
2150/// async fn new(_ctx: &Context) -> Self {
2151/// Self
2152/// }
2153///
2154/// #[response_body(&format!("attrs: {attr1}, {attr2}"))]
2155/// #[attribute("key1" => attr1: String, "key2" => attr2: i32)]
2156/// async fn handle(self, ctx: &Context) {}
2157/// }
2158/// ```
2159///
2160/// The macro accepts multiple `key => variable_name: Type` tuples separated by commas.
2161///
2162/// # Panics
2163///
2164/// This macro will panic if the requested attribute does not exist in the request context.
2165#[proc_macro_attribute]
2166pub fn attribute(attr: TokenStream, item: TokenStream) -> TokenStream {
2167 attribute_macro(attr, item, Position::Prologue)
2168}
2169
2170/// Extracts all attributes into a ThreadSafeAttributeStore variable.
2171///
2172/// This attribute macro retrieves all available attributes from the request context
2173/// and makes them available as a ThreadSafeAttributeStore for comprehensive attribute access.
2174///
2175/// # Usage
2176///
2177/// ```rust
2178/// use hyperlane::*;
2179/// use hyperlane_macros::*;
2180///
2181/// #[route("/attributes")]
2182/// struct Attributes;
2183///
2184/// impl ServerHook for Attributes {
2185/// async fn new(_ctx: &Context) -> Self {
2186/// Self
2187/// }
2188///
2189/// #[response_body(&format!("request attributes: {request_attributes:?}"))]
2190/// #[attributes(request_attributes)]
2191/// async fn handle(self, ctx: &Context) {}
2192/// }
2193///
2194/// impl Attributes {
2195/// #[attributes(request_attributes)]
2196/// async fn attributes_with_ref_self(&self, ctx: &Context) {}
2197/// }
2198///
2199/// #[attributes(request_attributes)]
2200/// async fn standalone_attributes_handler(ctx: &Context) {}
2201/// ```
2202///
2203/// The macro accepts a variable name that will contain a HashMap of all attributes.
2204/// The variable will be available as a HashMap in the function scope.
2205///
2206/// # Multi-Parameter Usage
2207///
2208/// ```rust
2209/// use hyperlane::*;
2210/// use hyperlane_macros::*;
2211///
2212/// #[route("/multi_attrs")]
2213/// struct MultiAttrs;
2214///
2215/// impl ServerHook for MultiAttrs {
2216/// async fn new(_ctx: &Context) -> Self {
2217/// Self
2218/// }
2219///
2220/// #[response_body(&format!("attrs1: {attrs1:?}, attrs2: {attrs2:?}"))]
2221/// #[attributes(attrs1, attrs2)]
2222/// async fn handle(self, ctx: &Context) {}
2223/// }
2224/// ```
2225///
2226/// The macro accepts multiple variable names separated by commas.
2227#[proc_macro_attribute]
2228pub fn attributes(attr: TokenStream, item: TokenStream) -> TokenStream {
2229 attributes_macro(attr, item, Position::Prologue)
2230}
2231
2232/// Extracts panic data into a variable wrapped in Option type.
2233///
2234/// This attribute macro retrieves panic information if a panic occurred during handling
2235/// and makes it available as an Option variable. The extracted value is wrapped
2236/// in an Option type to safely handle cases where no panic occurred.
2237///
2238/// # Usage
2239///
2240/// ```rust
2241/// use hyperlane::*;
2242/// use hyperlane_macros::*;
2243///
2244/// #[route("/task_panic_data_option")]
2245/// struct PanicDataOptionTest;
2246///
2247/// impl ServerHook for PanicDataOptionTest {
2248/// async fn new(_ctx: &Context) -> Self {
2249/// Self
2250/// }
2251///
2252/// #[response_body(&format!("Panic data: {task_panic_data_option:?}"))]
2253/// #[task_panic_data_option(task_panic_data_option)]
2254/// async fn handle(self, ctx: &Context) {}
2255/// }
2256///
2257/// impl PanicDataOptionTest {
2258/// #[task_panic_data_option(task_panic_data_option)]
2259/// async fn task_panic_data_option_with_ref_self(&self, ctx: &Context) {}
2260/// }
2261///
2262/// #[task_panic_data_option(task_panic_data_option)]
2263/// async fn standalone_task_panic_data_option_handler(ctx: &Context) {}
2264/// ```
2265///
2266/// The macro accepts a variable name that will contain the panic data.
2267/// The variable will be available as an `Option<PanicData>` in the function scope.
2268///
2269/// # Multi-Parameter Usage
2270///
2271/// ```rust
2272/// use hyperlane::*;
2273/// use hyperlane_macros::*;
2274///
2275/// #[route("/task_panic_data_option")]
2276/// struct MultiPanicDataOption;
2277///
2278/// impl ServerHook for MultiPanicDataOption {
2279/// async fn new(_ctx: &Context) -> Self {
2280/// Self
2281/// }
2282///
2283/// #[response_body(&format!("panic1: {panic1:?}, panic2: {panic2:?}"))]
2284/// #[task_panic_data_option(panic1, panic2)]
2285/// async fn handle(self, ctx: &Context) {}
2286/// }
2287/// ```
2288///
2289/// The macro accepts multiple variable names separated by commas.
2290#[proc_macro_attribute]
2291pub fn task_panic_data_option(attr: TokenStream, item: TokenStream) -> TokenStream {
2292 task_panic_data_option_macro(attr, item, Position::Prologue)
2293}
2294
2295/// Extracts panic data into a variable with panic on missing value.
2296///
2297/// This attribute macro retrieves panic information if a panic occurred during handling
2298/// and makes it available as a variable. If no panic data exists,
2299/// the function will panic with an error message.
2300///
2301/// # Usage
2302///
2303/// ```rust
2304/// use hyperlane::*;
2305/// use hyperlane_macros::*;
2306///
2307/// #[route("/task_panic_data")]
2308/// struct PanicDataTest;
2309///
2310/// impl ServerHook for PanicDataTest {
2311/// async fn new(_ctx: &Context) -> Self {
2312/// Self
2313/// }
2314///
2315/// #[response_body(&format!("Panic data: {task_panic_data}"))]
2316/// #[task_panic_data(task_panic_data)]
2317/// async fn handle(self, ctx: &Context) {}
2318/// }
2319///
2320/// impl PanicDataTest {
2321/// #[task_panic_data(task_panic_data)]
2322/// async fn task_panic_data_with_ref_self(&self, ctx: &Context) {}
2323/// }
2324///
2325/// #[task_panic_data(task_panic_data)]
2326/// async fn standalone_task_panic_data_handler(ctx: &Context) {}
2327/// ```
2328///
2329/// The macro accepts a variable name that will contain the panic data.
2330/// The variable will be available as a `PanicData` in the function scope.
2331///
2332/// # Multi-Parameter Usage
2333///
2334/// ```rust
2335/// use hyperlane::*;
2336/// use hyperlane_macros::*;
2337///
2338/// #[route("/task_panic_data")]
2339/// struct MultiPanicData;
2340///
2341/// impl ServerHook for MultiPanicData {
2342/// async fn new(_ctx: &Context) -> Self {
2343/// Self
2344/// }
2345///
2346/// #[response_body(&format!("panic1: {panic1}, panic2: {panic2}"))]
2347/// #[task_panic_data(panic1, panic2)]
2348/// async fn handle(self, ctx: &Context) {}
2349/// }
2350/// ```
2351///
2352/// The macro accepts multiple variable names separated by commas.
2353///
2354/// # Panics
2355///
2356/// This macro will panic if no panic data exists in the request context.
2357#[proc_macro_attribute]
2358pub fn task_panic_data(attr: TokenStream, item: TokenStream) -> TokenStream {
2359 task_panic_data_macro(attr, item, Position::Prologue)
2360}
2361
2362/// Extracts request error data into a variable wrapped in Option type.
2363///
2364/// This attribute macro retrieves request error information if an error occurred during handling
2365/// and makes it available as an Option variable. The extracted value is wrapped
2366/// in an Option type to safely handle cases where no error occurred.
2367///
2368/// # Usage
2369///
2370/// ```rust
2371/// use hyperlane::*;
2372/// use hyperlane_macros::*;
2373///
2374/// #[route("/request_error_data_option")]
2375/// struct RequestErrorDataOptionTest;
2376///
2377/// impl ServerHook for RequestErrorDataOptionTest {
2378/// async fn new(_ctx: &Context) -> Self {
2379/// Self
2380/// }
2381///
2382/// #[response_body(&format!("Request error data: {request_error_data_option:?}"))]
2383/// #[request_error_data_option(request_error_data_option)]
2384/// async fn handle(self, ctx: &Context) {}
2385/// }
2386///
2387/// impl RequestErrorDataOptionTest {
2388/// #[request_error_data_option(request_error_data_option)]
2389/// async fn request_error_data_option_with_ref_self(&self, ctx: &Context) {}
2390/// }
2391///
2392/// #[request_error_data_option(request_error_data_option)]
2393/// async fn standalone_request_error_data_option_handler(ctx: &Context) {}
2394/// ```
2395///
2396/// The macro accepts a variable name that will contain the request error data.
2397/// The variable will be available as an `Option<RequestError>` in the function scope.
2398///
2399/// # Multi-Parameter Usage
2400///
2401/// ```rust
2402/// use hyperlane::*;
2403/// use hyperlane_macros::*;
2404///
2405/// #[route("/request_error_data_option")]
2406/// struct MultiRequestErrorDataOption;
2407///
2408/// impl ServerHook for MultiRequestErrorDataOption {
2409/// async fn new(_ctx: &Context) -> Self {
2410/// Self
2411/// }
2412///
2413/// #[response_body(&format!("error1: {error1:?}, error2: {error2:?}"))]
2414/// #[request_error_data_option(error1, error2)]
2415/// async fn handle(self, ctx: &Context) {}
2416/// }
2417/// ```
2418///
2419/// The macro accepts multiple variable names separated by commas.
2420#[proc_macro_attribute]
2421pub fn request_error_data_option(attr: TokenStream, item: TokenStream) -> TokenStream {
2422 request_error_data_option_macro(attr, item, Position::Prologue)
2423}
2424
2425/// Extracts request error data into a variable with panic on missing value.
2426///
2427/// This attribute macro retrieves request error information if an error occurred during handling
2428/// and makes it available as a variable. If no error data exists,
2429/// the function will panic with an error message.
2430///
2431/// # Usage
2432///
2433/// ```rust
2434/// use hyperlane::*;
2435/// use hyperlane_macros::*;
2436///
2437/// #[route("/request_error_data")]
2438/// struct RequestErrorDataTest;
2439///
2440/// impl ServerHook for RequestErrorDataTest {
2441/// async fn new(_ctx: &Context) -> Self {
2442/// Self
2443/// }
2444///
2445/// #[response_body(&format!("Request error data: {request_error_data}"))]
2446/// #[request_error_data(request_error_data)]
2447/// async fn handle(self, ctx: &Context) {}
2448/// }
2449///
2450/// impl RequestErrorDataTest {
2451/// #[request_error_data(request_error_data)]
2452/// async fn request_error_data_with_ref_self(&self, ctx: &Context) {}
2453/// }
2454///
2455/// #[request_error_data(request_error_data)]
2456/// async fn standalone_request_error_data_handler(ctx: &Context) {}
2457/// ```
2458///
2459/// The macro accepts a variable name that will contain the request error data.
2460/// The variable will be available as a `RequestError` in the function scope.
2461///
2462/// # Multi-Parameter Usage
2463///
2464/// ```rust
2465/// use hyperlane::*;
2466/// use hyperlane_macros::*;
2467///
2468/// #[route("/request_error_data")]
2469/// struct MultiRequestErrorData;
2470///
2471/// impl ServerHook for MultiRequestErrorData {
2472/// async fn new(_ctx: &Context) -> Self {
2473/// Self
2474/// }
2475///
2476/// #[response_body(&format!("error1: {error1}, error2: {error2}"))]
2477/// #[request_error_data(error1, error2)]
2478/// async fn handle(self, ctx: &Context) {}
2479/// }
2480/// ```
2481///
2482/// The macro accepts multiple variable names separated by commas.
2483///
2484/// # Panics
2485///
2486/// This macro will panic if no request error data exists in the request context.
2487#[proc_macro_attribute]
2488pub fn request_error_data(attr: TokenStream, item: TokenStream) -> TokenStream {
2489 request_error_data_macro(attr, item, Position::Prologue)
2490}
2491
2492/// Extracts a specific route parameter into a variable wrapped in Option type.
2493///
2494/// This attribute macro retrieves a specific route parameter by key and makes it
2495/// available as an Option variable. Route parameters are extracted from the URL path segments
2496/// and wrapped in an Option type to safely handle cases where the parameter may not exist.
2497///
2498/// # Usage
2499///
2500/// ```rust
2501/// use hyperlane::*;
2502/// use hyperlane_macros::*;
2503///
2504/// #[route("/route_param_option/:test")]
2505/// struct RouteParam;
2506///
2507/// impl ServerHook for RouteParam {
2508/// async fn new(_ctx: &Context) -> Self {
2509/// Self
2510/// }
2511///
2512/// #[response_body(&format!("route param: {request_route_param:?}"))]
2513/// #[route_param_option("test" => request_route_param)]
2514/// async fn handle(self, ctx: &Context) {}
2515/// }
2516///
2517/// impl RouteParam {
2518/// #[route_param_option("test" => request_route_param)]
2519/// async fn route_param_with_ref_self(&self, ctx: &Context) {}
2520/// }
2521///
2522/// #[route_param_option("test" => request_route_param)]
2523/// async fn standalone_route_param_handler(ctx: &Context) {}
2524/// ```
2525///
2526/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
2527/// The variable will be available as an `Option<String>` in the function scope.
2528///
2529/// # Multi-Parameter Usage
2530///
2531/// ```rust
2532/// use hyperlane::*;
2533/// use hyperlane_macros::*;
2534///
2535/// #[route("/multi_param/:id/:name")]
2536/// struct MultiParam;
2537///
2538/// impl ServerHook for MultiParam {
2539/// async fn new(_ctx: &Context) -> Self {
2540/// Self
2541/// }
2542///
2543/// #[response_body(&format!("id: {id:?}, name: {name:?}"))]
2544/// #[route_param_option("id" => id, "name" => name)]
2545/// async fn handle(self, ctx: &Context) {}
2546/// }
2547/// ```
2548///
2549/// The macro accepts multiple `"key" => variable_name` pairs separated by commas.
2550#[proc_macro_attribute]
2551pub fn route_param_option(attr: TokenStream, item: TokenStream) -> TokenStream {
2552 route_param_option_macro(attr, item, Position::Prologue)
2553}
2554
2555/// Extracts a specific route parameter into a variable with panic on missing value.
2556///
2557/// This attribute macro retrieves a specific route parameter by key and makes it
2558/// available as a variable. Route parameters are extracted from the URL path segments.
2559/// If the requested route parameter does not exist, the function will panic with an error message.
2560///
2561/// # Usage
2562///
2563/// ```rust
2564/// use hyperlane::*;
2565/// use hyperlane_macros::*;
2566///
2567/// #[route("/route_param/:test")]
2568/// struct RouteParam;
2569///
2570/// impl ServerHook for RouteParam {
2571/// async fn new(_ctx: &Context) -> Self {
2572/// Self
2573/// }
2574///
2575/// #[response_body(&format!("route param: {request_route_param:?}"))]
2576/// #[route_param("test" => request_route_param)]
2577/// async fn handle(self, ctx: &Context) {}
2578/// }
2579///
2580/// impl RouteParam {
2581/// #[route_param("test" => request_route_param)]
2582/// async fn route_param_with_ref_self(&self, ctx: &Context) {}
2583/// }
2584///
2585/// #[route_param("test" => request_route_param)]
2586/// async fn standalone_route_param_handler(ctx: &Context) {}
2587/// ```
2588///
2589/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
2590/// The variable will be available as an `String` in the function scope.
2591///
2592///
2593/// # Multi-Parameter Usage
2594///
2595/// ```rust
2596/// use hyperlane::*;
2597/// use hyperlane_macros::*;
2598///
2599/// #[route("/multi_param/:id/:name")]
2600/// struct MultiParam;
2601///
2602/// impl ServerHook for MultiParam {
2603/// async fn new(_ctx: &Context) -> Self {
2604/// Self
2605/// }
2606///
2607/// #[response_body(&format!("id: {id:?}, name: {name:?}"))]
2608/// #[route_param("id" => id, "name" => name)]
2609/// async fn handle(self, ctx: &Context) {}
2610/// }
2611/// ```
2612///
2613/// The macro accepts multiple `"key" => variable_name` pairs separated by commas.
2614///
2615/// # Panics
2616///
2617/// This macro will panic if the requested route parameter does not exist in the URL path.
2618#[proc_macro_attribute]
2619pub fn route_param(attr: TokenStream, item: TokenStream) -> TokenStream {
2620 route_param_macro(attr, item, Position::Prologue)
2621}
2622
2623/// Extracts all route parameters into a collection variable.
2624///
2625/// This attribute macro retrieves all available route parameters from the URL path
2626/// and makes them available as a collection for comprehensive route parameter access.
2627///
2628/// # Usage
2629///
2630/// ```rust
2631/// use hyperlane::*;
2632/// use hyperlane_macros::*;
2633///
2634/// #[route("/route_params/:test")]
2635/// struct RouteParams;
2636///
2637/// impl ServerHook for RouteParams {
2638/// async fn new(_ctx: &Context) -> Self {
2639/// Self
2640/// }
2641///
2642/// #[response_body(&format!("request route params: {request_route_params:?}"))]
2643/// #[route_params(request_route_params)]
2644/// async fn handle(self, ctx: &Context) {}
2645/// }
2646///
2647/// impl RouteParams {
2648/// #[route_params(request_route_params)]
2649/// async fn route_params_with_ref_self(&self, ctx: &Context) {}
2650/// }
2651///
2652/// #[route_params(request_route_params)]
2653/// async fn standalone_route_params_handler(ctx: &Context) {}
2654/// ```
2655///
2656/// The macro accepts a variable name that will contain all route parameters.
2657/// The variable will be available as a RouteParams type in the function scope.
2658///
2659/// # Multi-Parameter Usage
2660///
2661/// ```rust
2662/// use hyperlane::*;
2663/// use hyperlane_macros::*;
2664///
2665/// #[route("/multi_params/:id")]
2666/// struct MultiParams;
2667///
2668/// impl ServerHook for MultiParams {
2669/// async fn new(_ctx: &Context) -> Self {
2670/// Self
2671/// }
2672///
2673/// #[response_body(&format!("params1: {params1:?}, params2: {params2:?}"))]
2674/// #[route_params(params1, params2)]
2675/// async fn handle(self, ctx: &Context) {}
2676/// }
2677/// ```
2678///
2679/// The macro accepts multiple variable names separated by commas.
2680#[proc_macro_attribute]
2681pub fn route_params(attr: TokenStream, item: TokenStream) -> TokenStream {
2682 route_params_macro(attr, item, Position::Prologue)
2683}
2684
2685/// Extracts a specific request query parameter into a variable wrapped in Option type.
2686///
2687/// This attribute macro retrieves a specific request query parameter by key and makes it
2688/// available as an Option variable. Query parameters are extracted from the URL request query string
2689/// and wrapped in an Option type to safely handle cases where the parameter may not exist.
2690///
2691/// # Usage
2692///
2693/// ```rust
2694/// use hyperlane::*;
2695/// use hyperlane_macros::*;
2696///
2697/// #[route("/request_query_option")]
2698/// struct RequestQuery;
2699///
2700/// impl ServerHook for RequestQuery {
2701/// async fn new(_ctx: &Context) -> Self {
2702/// Self
2703/// }
2704///
2705/// #[prologue_macros(
2706/// request_query_option("test" => request_query_option),
2707/// response_body(&format!("request query: {request_query_option:?}")),
2708/// send
2709/// )]
2710/// async fn handle(self, ctx: &Context) {}
2711/// }
2712///
2713/// impl RequestQuery {
2714/// #[request_query_option("test" => request_query_option)]
2715/// async fn request_query_with_ref_self(&self, ctx: &Context) {}
2716/// }
2717///
2718/// #[request_query_option("test" => request_query_option)]
2719/// async fn standalone_request_query_handler(ctx: &Context) {}
2720/// ```
2721///
2722/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
2723/// The variable will be available as an `Option<RequestQuerysValue>` in the function scope.
2724///
2725/// Supports multiple parameters: `#[request_query_option("k1" => v1, "k2" => v2)]`
2726#[proc_macro_attribute]
2727pub fn request_query_option(attr: TokenStream, item: TokenStream) -> TokenStream {
2728 request_query_option_macro(attr, item, Position::Prologue)
2729}
2730
2731/// Extracts a specific request query parameter into a variable with panic on missing value.
2732///
2733/// This attribute macro retrieves a specific request query parameter by key and makes it
2734/// available as a variable. Query parameters are extracted from the URL request query string.
2735/// If the requested query parameter does not exist, the function will panic with an error message.
2736///
2737/// # Usage
2738///
2739/// ```rust
2740/// use hyperlane::*;
2741/// use hyperlane_macros::*;
2742///
2743/// #[route("/request_query")]
2744/// struct RequestQuery;
2745///
2746/// impl ServerHook for RequestQuery {
2747/// async fn new(_ctx: &Context) -> Self {
2748/// Self
2749/// }
2750///
2751/// #[prologue_macros(
2752/// request_query("test" => request_query),
2753/// response_body(&format!("request query: {request_query}")),
2754/// send
2755/// )]
2756/// async fn handle(self, ctx: &Context) {}
2757/// }
2758///
2759/// impl RequestQuery {
2760/// #[request_query("test" => request_query)]
2761/// async fn request_query_with_ref_self(&self, ctx: &Context) {}
2762/// }
2763///
2764/// #[request_query("test" => request_query)]
2765/// async fn standalone_request_query_handler(ctx: &Context) {}
2766/// ```
2767///
2768/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
2769/// The variable will be available as an `RequestQuerysValue` in the function scope.
2770///
2771/// Supports multiple parameters: `#[request_query("k1" => v1, "k2" => v2)]`
2772///
2773/// # Panics
2774///
2775/// This macro will panic if the requested query parameter does not exist in the URL query string.
2776#[proc_macro_attribute]
2777pub fn request_query(attr: TokenStream, item: TokenStream) -> TokenStream {
2778 request_query_macro(attr, item, Position::Prologue)
2779}
2780
2781/// Extracts all request query parameters into a RequestQuerys variable.
2782///
2783/// This attribute macro retrieves all available request query parameters from the URL request query string
2784/// and makes them available as a RequestQuerys for comprehensive request query parameter access.
2785///
2786/// # Usage
2787///
2788/// ```rust
2789/// use hyperlane::*;
2790/// use hyperlane_macros::*;
2791///
2792/// #[route("/request_querys")]
2793/// struct RequestQuerys;
2794///
2795/// impl ServerHook for RequestQuerys {
2796/// async fn new(_ctx: &Context) -> Self {
2797/// Self
2798/// }
2799///
2800/// #[prologue_macros(
2801/// request_querys(request_querys),
2802/// response_body(&format!("request querys: {request_querys:?}")),
2803/// send
2804/// )]
2805/// async fn handle(self, ctx: &Context) {}
2806/// }
2807///
2808/// impl RequestQuerys {
2809/// #[request_querys(request_querys)]
2810/// async fn request_querys_with_ref_self(&self, ctx: &Context) {}
2811/// }
2812///
2813/// #[request_querys(request_querys)]
2814/// async fn standalone_request_querys_handler(ctx: &Context) {}
2815/// ```
2816///
2817/// The macro accepts a variable name that will contain all request query parameters.
2818/// The variable will be available as a collection in the function scope.
2819///
2820/// Supports multiple parameters: `#[request_querys(querys1, querys2)]`
2821#[proc_macro_attribute]
2822pub fn request_querys(attr: TokenStream, item: TokenStream) -> TokenStream {
2823 request_querys_macro(attr, item, Position::Prologue)
2824}
2825
2826/// Extracts a specific HTTP request header into a variable wrapped in Option type.
2827///
2828/// This attribute macro retrieves a specific HTTP request header by name and makes it
2829/// available as an Option variable. Header values are extracted from the request request headers collection
2830/// and wrapped in an Option type to safely handle cases where the header may not exist.
2831///
2832/// # Usage
2833///
2834/// ```rust
2835/// use hyperlane::*;
2836/// use hyperlane_macros::*;
2837///
2838/// #[route("/request_header_option")]
2839/// struct RequestHeader;
2840///
2841/// impl ServerHook for RequestHeader {
2842/// async fn new(_ctx: &Context) -> Self {
2843/// Self
2844/// }
2845///
2846/// #[prologue_macros(
2847/// request_header_option(HOST => request_header_option),
2848/// response_body(&format!("request header: {request_header_option:?}")),
2849/// send
2850/// )]
2851/// async fn handle(self, ctx: &Context) {}
2852/// }
2853///
2854/// impl RequestHeader {
2855/// #[request_header_option(HOST => request_header_option)]
2856/// async fn request_header_with_ref_self(&self, ctx: &Context) {}
2857/// }
2858///
2859/// #[request_header_option(HOST => request_header_option)]
2860/// async fn standalone_request_header_handler(ctx: &Context) {}
2861/// ```
2862///
2863/// The macro accepts a request header name-to-variable mapping in the format `HEADER_NAME => variable_name`
2864/// or `"Header-Name" => variable_name`. The variable will be available as an `Option<RequestHeadersValueItem>`.
2865#[proc_macro_attribute]
2866pub fn request_header_option(attr: TokenStream, item: TokenStream) -> TokenStream {
2867 request_header_option_macro(attr, item, Position::Prologue)
2868}
2869
2870/// Extracts a specific HTTP request header into a variable with panic on missing value.
2871///
2872/// This attribute macro retrieves a specific HTTP request header by name and makes it
2873/// available as a variable. Header values are extracted from the request request headers collection.
2874/// If the requested header does not exist, the function will panic with an error message.
2875///
2876/// # Usage
2877///
2878/// ```rust
2879/// use hyperlane::*;
2880/// use hyperlane_macros::*;
2881///
2882/// #[route("/request_header")]
2883/// struct RequestHeader;
2884///
2885/// impl ServerHook for RequestHeader {
2886/// async fn new(_ctx: &Context) -> Self {
2887/// Self
2888/// }
2889///
2890/// #[prologue_macros(
2891/// request_header(HOST => request_header),
2892/// response_body(&format!("request header: {request_header}")),
2893/// send
2894/// )]
2895/// async fn handle(self, ctx: &Context) {}
2896/// }
2897///
2898/// impl RequestHeader {
2899/// #[request_header(HOST => request_header)]
2900/// async fn request_header_with_ref_self(&self, ctx: &Context) {}
2901/// }
2902///
2903/// #[request_header(HOST => request_header)]
2904/// async fn standalone_request_header_handler(ctx: &Context) {}
2905/// ```
2906///
2907/// The macro accepts a request header name-to-variable mapping in the format `HEADER_NAME => variable_name`
2908/// or `"Header-Name" => variable_name`. The variable will be available as an `RequestHeadersValueItem`.
2909///
2910/// # Panics
2911///
2912/// This macro will panic if the requested header does not exist in the HTTP request headers.
2913#[proc_macro_attribute]
2914pub fn request_header(attr: TokenStream, item: TokenStream) -> TokenStream {
2915 request_header_macro(attr, item, Position::Prologue)
2916}
2917
2918/// Extracts all HTTP request headers into a collection variable.
2919///
2920/// This attribute macro retrieves all available HTTP request headers from the request
2921/// and makes them available as a collection for comprehensive request header access.
2922///
2923/// # Usage
2924///
2925/// ```rust
2926/// use hyperlane::*;
2927/// use hyperlane_macros::*;
2928///
2929/// #[route("/request_headers")]
2930/// struct RequestHeaders;
2931///
2932/// impl ServerHook for RequestHeaders {
2933/// async fn new(_ctx: &Context) -> Self {
2934/// Self
2935/// }
2936///
2937/// #[prologue_macros(
2938/// request_headers(request_headers),
2939/// response_body(&format!("request headers: {request_headers:?}")),
2940/// send
2941/// )]
2942/// async fn handle(self, ctx: &Context) {}
2943/// }
2944///
2945/// impl RequestHeaders {
2946/// #[request_headers(request_headers)]
2947/// async fn request_headers_with_ref_self(&self, ctx: &Context) {}
2948/// }
2949///
2950/// #[request_headers(request_headers)]
2951/// async fn standalone_request_headers_handler(ctx: &Context) {}
2952/// ```
2953///
2954/// The macro accepts a variable name that will contain all HTTP request headers.
2955/// The variable will be available as a RequestHeaders type in the function scope.
2956#[proc_macro_attribute]
2957pub fn request_headers(attr: TokenStream, item: TokenStream) -> TokenStream {
2958 request_headers_macro(attr, item, Position::Prologue)
2959}
2960
2961/// Extracts a specific cookie value or all cookies into a variable wrapped in Option type.
2962///
2963/// This attribute macro supports two syntaxes:
2964/// 1. `cookie(key => variable_name)` - Extract a specific cookie value by key, wrapped in Option
2965/// 2. `cookie(variable_name)` - Extract all cookies as a raw string, wrapped in Option
2966///
2967/// # Usage
2968///
2969/// ```rust
2970/// use hyperlane::*;
2971/// use hyperlane_macros::*;
2972///
2973/// #[route("/cookie")]
2974/// struct Cookie;
2975///
2976/// impl ServerHook for Cookie {
2977/// async fn new(_ctx: &Context) -> Self {
2978/// Self
2979/// }
2980///
2981/// #[response_body(&format!("Session cookie: {session_cookie1_option:?}, {session_cookie2_option:?}"))]
2982/// #[request_cookie_option("test1" => session_cookie1_option, "test2" => session_cookie2_option)]
2983/// async fn handle(self, ctx: &Context) {}
2984/// }
2985///
2986/// impl Cookie {
2987/// #[response_body(&format!("Session cookie: {session_cookie1_option:?}, {session_cookie2_option:?}"))]
2988/// #[request_cookie_option("test1" => session_cookie1_option, "test2" => session_cookie2_option)]
2989/// async fn request_cookie_with_ref_self(&self, ctx: &Context) {}
2990/// }
2991///
2992/// #[response_body(&format!("Session cookie: {session_cookie1_option:?}, {session_cookie2_option:?}"))]
2993/// #[request_cookie_option("test1" => session_cookie1_option, "test2" => session_cookie2_option)]
2994/// async fn standalone_request_cookie_handler(ctx: &Context) {}
2995/// ```
2996///
2997/// For specific cookie extraction, the variable will be available as `Option<String>`.
2998/// For all cookies extraction, the variable will be available as `String`.
2999#[proc_macro_attribute]
3000pub fn request_cookie_option(attr: TokenStream, item: TokenStream) -> TokenStream {
3001 request_cookie_option_macro(attr, item, Position::Prologue)
3002}
3003
3004/// Extracts a specific cookie value or all cookies into a variable with panic on missing value.
3005///
3006/// This attribute macro supports two syntaxes:
3007/// 1. `cookie(key => variable_name)` - Extract a specific cookie value by key, panics if missing
3008/// 2. `cookie(variable_name)` - Extract all cookies as a raw string, panics if missing
3009///
3010/// # Usage
3011///
3012/// ```rust
3013/// use hyperlane::*;
3014/// use hyperlane_macros::*;
3015///
3016/// #[route("/cookie")]
3017/// struct Cookie;
3018///
3019/// impl ServerHook for Cookie {
3020/// async fn new(_ctx: &Context) -> Self {
3021/// Self
3022/// }
3023///
3024/// #[response_body(&format!("Session cookie: {session_cookie1}, {session_cookie2}"))]
3025/// #[request_cookie("test1" => session_cookie1, "test2" => session_cookie2)]
3026/// async fn handle(self, ctx: &Context) {}
3027/// }
3028///
3029/// impl Cookie {
3030/// #[response_body(&format!("Session cookie: {session_cookie1}, {session_cookie2}"))]
3031/// #[request_cookie("test1" => session_cookie1, "test2" => session_cookie2)]
3032/// async fn request_cookie_with_ref_self(&self, ctx: &Context) {}
3033/// }
3034///
3035/// #[response_body(&format!("Session cookie: {session_cookie1}, {session_cookie2}"))]
3036/// #[request_cookie("test1" => session_cookie1, "test2" => session_cookie2)]
3037/// async fn standalone_request_cookie_handler(ctx: &Context) {}
3038/// ```
3039///
3040/// For specific cookie extraction, the variable will be available as `String`.
3041/// For all cookies extraction, the variable will be available as `String`.
3042///
3043/// # Panics
3044///
3045/// This macro will panic if the requested cookie does not exist in the HTTP request headers.
3046#[proc_macro_attribute]
3047pub fn request_cookie(attr: TokenStream, item: TokenStream) -> TokenStream {
3048 request_cookie_macro(attr, item, Position::Prologue)
3049}
3050
3051/// Extracts all cookies as a raw string into a variable.
3052///
3053/// This attribute macro retrieves the entire Cookie header from the request and makes it
3054/// available as a String variable. If no Cookie header is present, an empty string is used.
3055///
3056/// # Usage
3057///
3058/// ```rust
3059/// use hyperlane::*;
3060/// use hyperlane_macros::*;
3061///
3062/// #[route("/cookies")]
3063/// struct Cookies;
3064///
3065/// impl ServerHook for Cookies {
3066/// async fn new(_ctx: &Context) -> Self {
3067/// Self
3068/// }
3069///
3070/// #[response_body(&format!("All cookies: {cookie_value:?}"))]
3071/// #[request_cookies(cookie_value)]
3072/// async fn handle(self, ctx: &Context) {}
3073/// }
3074///
3075/// impl Cookies {
3076/// #[request_cookies(cookie_value)]
3077/// async fn request_cookies_with_ref_self(&self, ctx: &Context) {}
3078/// }
3079///
3080/// #[request_cookies(cookie_value)]
3081/// async fn standalone_request_cookies_handler(ctx: &Context) {}
3082/// ```
3083///
3084/// The macro accepts a variable name that will contain all cookies.
3085/// The variable will be available as a Cookies type in the function scope.
3086#[proc_macro_attribute]
3087pub fn request_cookies(attr: TokenStream, item: TokenStream) -> TokenStream {
3088 request_cookies_macro(attr, item, Position::Prologue)
3089}
3090
3091/// Extracts the HTTP request version into a variable.
3092///
3093/// This attribute macro retrieves the HTTP version from the request and makes it
3094/// available as a variable. The version represents the HTTP protocol version used.
3095///
3096/// # Usage
3097///
3098/// ```rust
3099/// use hyperlane::*;
3100/// use hyperlane_macros::*;
3101///
3102/// #[route("/request_version")]
3103/// struct RequestVersionTest;
3104///
3105/// impl ServerHook for RequestVersionTest {
3106/// async fn new(_ctx: &Context) -> Self {
3107/// Self
3108/// }
3109///
3110/// #[response_body(&format!("HTTP Version: {http_version}"))]
3111/// #[request_version(http_version)]
3112/// async fn handle(self, ctx: &Context) {}
3113/// }
3114///
3115/// impl RequestVersionTest {
3116/// #[request_version(http_version)]
3117/// async fn request_version_with_ref_self(&self, ctx: &Context) {}
3118/// }
3119///
3120/// #[request_version(http_version)]
3121/// async fn standalone_request_version_handler(ctx: &Context) {}
3122/// ```
3123///
3124/// The macro accepts a variable name that will contain the HTTP request version.
3125/// The variable will be available as a RequestVersion type in the function scope.
3126#[proc_macro_attribute]
3127pub fn request_version(attr: TokenStream, item: TokenStream) -> TokenStream {
3128 request_version_macro(attr, item, Position::Prologue)
3129}
3130
3131/// Extracts the HTTP request path into a variable.
3132///
3133/// This attribute macro retrieves the request path from the HTTP request and makes it
3134/// available as a variable. The path represents the URL path portion of the request.
3135///
3136/// # Usage
3137///
3138/// ```rust
3139/// use hyperlane::*;
3140/// use hyperlane_macros::*;
3141///
3142/// #[route("/request_path")]
3143/// struct RequestPathTest;
3144///
3145/// impl ServerHook for RequestPathTest {
3146/// async fn new(_ctx: &Context) -> Self {
3147/// Self
3148/// }
3149///
3150/// #[response_body(&format!("Request Path: {request_path}"))]
3151/// #[request_path(request_path)]
3152/// async fn handle(self, ctx: &Context) {}
3153/// }
3154///
3155/// impl RequestPathTest {
3156/// #[request_path(request_path)]
3157/// async fn request_path_with_ref_self(&self, ctx: &Context) {}
3158/// }
3159///
3160/// #[request_path(request_path)]
3161/// async fn standalone_request_path_handler(ctx: &Context) {}
3162/// ```
3163///
3164/// The macro accepts a variable name that will contain the HTTP request path.
3165/// The variable will be available as a RequestPath type in the function scope.
3166#[proc_macro_attribute]
3167pub fn request_path(attr: TokenStream, item: TokenStream) -> TokenStream {
3168 request_path_macro(attr, item, Position::Prologue)
3169}
3170
3171/// Creates a new instance of a specified type with a given variable name.
3172///
3173/// This attribute macro generates an instance initialization at the beginning of the function.
3174///
3175/// # Usage
3176///
3177/// ```rust,no_run
3178/// use hyperlane::*;
3179/// use hyperlane_macros::*;
3180///
3181/// #[hyperlane(server: Server)]
3182/// #[hyperlane(config: ServerConfig)]
3183/// #[tokio::main]
3184/// async fn main() {
3185/// config.disable_nodelay().await;
3186/// server.config(config).await;
3187/// let server_hook: ServerControlHook = server.run().await.unwrap_or_default();
3188/// server_hook.wait().await;
3189/// }
3190/// ```
3191///
3192/// The macro accepts a `variable_name: Type` pair.
3193/// The variable will be available as an instance of the specified type in the function scope.
3194#[proc_macro_attribute]
3195pub fn hyperlane(attr: TokenStream, item: TokenStream) -> TokenStream {
3196 hyperlane_macro(attr, item)
3197}
3198
3199/// Registers a function as a route handler.
3200///
3201/// This attribute macro registers the decorated function as a route handler for a given path.
3202/// This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
3203///
3204/// # Usage
3205///
3206/// ```rust
3207/// use hyperlane::*;
3208/// use hyperlane_macros::*;
3209///
3210/// #[route("/response")]
3211/// struct Response;
3212///
3213/// impl ServerHook for Response {
3214/// async fn new(_ctx: &Context) -> Self {
3215/// Self
3216/// }
3217///
3218/// #[response_body("response")]
3219/// async fn handle(self, ctx: &Context) {}
3220/// }
3221/// ```
3222///
3223/// # Parameters
3224///
3225/// - `path`: String literal defining the route path
3226///
3227/// # Dependencies
3228///
3229/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
3230#[proc_macro_attribute]
3231pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
3232 route_macro(attr, item)
3233}
3234
3235/// Registers a function as a request middleware.
3236///
3237/// This attribute macro registers the decorated function to be executed as a middleware
3238/// for incoming requests. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
3239///
3240/// # Note
3241///
3242/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
3243///
3244/// # Usage
3245///
3246/// ```rust
3247/// use hyperlane::*;
3248/// use hyperlane_macros::*;
3249///
3250/// #[request_middleware]
3251/// struct RequestMiddleware;
3252///
3253/// impl ServerHook for RequestMiddleware {
3254/// async fn new(_ctx: &Context) -> Self {
3255/// Self
3256/// }
3257///
3258/// #[epilogue_macros(
3259/// response_status_code(200),
3260/// response_version(HttpVersion::Http1_1),
3261/// response_header(SERVER => HYPERLANE)
3262/// )]
3263/// async fn handle(self, ctx: &Context) {}
3264/// }
3265/// ```
3266///
3267/// # Dependencies
3268///
3269/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
3270#[proc_macro_attribute]
3271pub fn request_middleware(attr: TokenStream, item: TokenStream) -> TokenStream {
3272 request_middleware_macro(attr, item)
3273}
3274
3275/// Registers a function as a response middleware.
3276///
3277/// This attribute macro registers the decorated function to be executed as a middleware
3278/// for outgoing responses. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
3279///
3280/// # Note
3281///
3282/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
3283///
3284/// # Usage
3285///
3286/// ```rust
3287/// use hyperlane::*;
3288/// use hyperlane_macros::*;
3289///
3290/// #[response_middleware]
3291/// struct ResponseMiddleware1;
3292///
3293/// impl ServerHook for ResponseMiddleware1 {
3294/// async fn new(_ctx: &Context) -> Self {
3295/// Self
3296/// }
3297///
3298/// async fn handle(self, ctx: &Context) {}
3299/// }
3300/// ```
3301///
3302/// # Dependencies
3303///
3304/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
3305#[proc_macro_attribute]
3306pub fn response_middleware(attr: TokenStream, item: TokenStream) -> TokenStream {
3307 response_middleware_macro(attr, item)
3308}
3309
3310/// Registers a function as a panic hook.
3311///
3312/// This attribute macro registers the decorated function to handle panics that occur
3313/// during request processing. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
3314///
3315/// # Note
3316///
3317/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
3318///
3319/// # Usage
3320///
3321/// ```rust
3322/// use hyperlane::*;
3323/// use hyperlane_macros::*;
3324///
3325/// #[task_panic]
3326/// #[task_panic(1)]
3327/// #[task_panic("2")]
3328/// struct PanicHook;
3329///
3330/// impl ServerHook for PanicHook {
3331/// async fn new(_ctx: &Context) -> Self {
3332/// Self
3333/// }
3334///
3335/// #[epilogue_macros(response_body("task_panic"), send)]
3336/// async fn handle(self, ctx: &Context) {}
3337/// }
3338/// ```
3339///
3340/// # Dependencies
3341///
3342/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
3343#[proc_macro_attribute]
3344pub fn task_panic(attr: TokenStream, item: TokenStream) -> TokenStream {
3345 task_panic_macro(attr, item)
3346}
3347
3348/// Registers a function as a request error hook.
3349///
3350/// This attribute macro registers the decorated function to handle request errors that occur
3351/// during request processing. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
3352///
3353/// # Note
3354///
3355/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
3356///
3357/// # Usage
3358///
3359/// ```rust
3360/// use hyperlane::*;
3361/// use hyperlane_macros::*;
3362///
3363/// #[request_error]
3364/// #[request_error(1)]
3365/// #[request_error("2")]
3366/// struct RequestErrorHook;
3367///
3368/// impl ServerHook for RequestErrorHook {
3369/// async fn new(_ctx: &Context) -> Self {
3370/// Self
3371/// }
3372///
3373/// #[epilogue_macros(response_body("request_error"), send)]
3374/// async fn handle(self, ctx: &Context) {}
3375/// }
3376/// ```
3377///
3378/// # Dependencies
3379///
3380/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
3381#[proc_macro_attribute]
3382pub fn request_error(attr: TokenStream, item: TokenStream) -> TokenStream {
3383 request_error_macro(attr, item)
3384}
3385
3386/// Injects a list of macros before the decorated function.
3387///
3388/// The macros are applied in head-insertion order, meaning the first macro in the list
3389/// is the outermost macro.
3390///
3391/// # Usage
3392///
3393/// ```rust
3394/// use hyperlane::*;
3395/// use hyperlane_macros::*;
3396///
3397/// #[route("/prologue_macros")]
3398/// struct PrologueMacros;
3399///
3400/// impl ServerHook for PrologueMacros {
3401/// async fn new(_ctx: &Context) -> Self {
3402/// Self
3403/// }
3404///
3405/// #[prologue_macros(post, response_body("prologue_macros"), send)]
3406/// async fn handle(self, ctx: &Context) {}
3407/// }
3408/// ```
3409#[proc_macro_attribute]
3410pub fn prologue_macros(attr: TokenStream, item: TokenStream) -> TokenStream {
3411 prologue_macros_macro(attr, item)
3412}
3413
3414/// Injects a list of macros after the decorated function.
3415///
3416/// The macros are applied in tail-insertion order, meaning the last macro in the list
3417/// is the outermost macro.
3418///
3419/// # Usage
3420///
3421/// ```rust
3422/// use hyperlane::*;
3423/// use hyperlane_macros::*;
3424///
3425/// #[response_middleware(2)]
3426/// struct ResponseMiddleware2;
3427///
3428/// impl ServerHook for ResponseMiddleware2 {
3429/// async fn new(_ctx: &Context) -> Self {
3430/// Self
3431/// }
3432///
3433/// #[epilogue_macros(try_send, flush)]
3434/// async fn handle(self, ctx: &Context) {}
3435/// }
3436/// ```
3437#[proc_macro_attribute]
3438pub fn epilogue_macros(attr: TokenStream, item: TokenStream) -> TokenStream {
3439 epilogue_macros_macro(attr, item)
3440}
3441
3442/// Automatically tries to send the complete response after function execution.
3443///
3444/// This attribute macro ensures that the response (request headers and body) is automatically tried to be sent
3445/// to the client after the function completes execution.
3446///
3447/// # Usage
3448///
3449/// ```rust
3450/// use hyperlane::*;
3451/// use hyperlane_macros::*;
3452///
3453/// #[route("/try_send")]
3454/// struct TrySendTest;
3455///
3456/// impl ServerHook for TrySendTest {
3457/// async fn new(_ctx: &Context) -> Self {
3458/// Self
3459/// }
3460///
3461/// #[epilogue_macros(try_send)]
3462/// async fn handle(self, ctx: &Context) {}
3463/// }
3464///
3465/// impl TrySendTest {
3466/// #[try_send]
3467/// async fn try_send_with_ref_self(&self, ctx: &Context) {}
3468/// }
3469///
3470/// #[try_send]
3471/// async fn standalone_try_send_handler(ctx: &Context) {}
3472/// ```
3473///
3474/// The macro takes no parameters and should be applied directly to async functions
3475/// that accept a `&Context` parameter.
3476#[proc_macro_attribute]
3477pub fn try_send(_attr: TokenStream, item: TokenStream) -> TokenStream {
3478 try_send_macro(item, Position::Epilogue)
3479}
3480
3481/// Automatically sends the complete response after function execution.
3482///
3483/// This attribute macro ensures that the response (request headers and body) is automatically sent
3484/// to the client after the function completes execution.
3485///
3486/// # Usage
3487///
3488/// ```rust
3489/// use hyperlane::*;
3490/// use hyperlane_macros::*;
3491///
3492/// #[route("/send")]
3493/// struct SendTest;
3494///
3495/// impl ServerHook for SendTest {
3496/// async fn new(_ctx: &Context) -> Self {
3497/// Self
3498/// }
3499///
3500/// #[epilogue_macros(send)]
3501/// async fn handle(self, ctx: &Context) {}
3502/// }
3503///
3504/// impl SendTest {
3505/// #[send]
3506/// async fn send_with_ref_self(&self, ctx: &Context) {}
3507/// }
3508///
3509/// #[send]
3510/// async fn standalone_send_handler(ctx: &Context) {}
3511/// ```
3512///
3513/// The macro takes no parameters and should be applied directly to async functions
3514/// that accept a `&Context` parameter.
3515///
3516/// # Panics
3517///
3518/// This macro will panic if the send operation fails.
3519#[proc_macro_attribute]
3520pub fn send(_attr: TokenStream, item: TokenStream) -> TokenStream {
3521 send_macro(item, Position::Epilogue)
3522}
3523
3524/// Automatically tries to send only the response body after function execution.
3525///
3526/// This attribute macro ensures that only the response body is automatically tried to be sent
3527/// to the client after the function completes, handling request headers separately.
3528///
3529/// # Usage
3530///
3531/// ```rust
3532/// use hyperlane::*;
3533/// use hyperlane_macros::*;
3534///
3535/// #[route("/try_send_body")]
3536/// struct TrySendBodyTest;
3537///
3538/// impl ServerHook for TrySendBodyTest {
3539/// async fn new(_ctx: &Context) -> Self {
3540/// Self
3541/// }
3542///
3543/// #[epilogue_macros(try_send_body)]
3544/// async fn handle(self, ctx: &Context) {}
3545/// }
3546///
3547/// impl TrySendBodyTest {
3548/// #[try_send_body]
3549/// async fn try_send_body_with_ref_self(&self, ctx: &Context) {}
3550/// }
3551///
3552/// #[try_send_body]
3553/// async fn standalone_try_send_body_handler(ctx: &Context) {}
3554/// ```
3555///
3556/// The macro takes no parameters and should be applied directly to async functions
3557/// that accept a `&Context` parameter.
3558#[proc_macro_attribute]
3559pub fn try_send_body(_attr: TokenStream, item: TokenStream) -> TokenStream {
3560 try_send_body_macro(item, Position::Epilogue)
3561}
3562
3563/// Automatically sends only the response body after function execution.
3564///
3565/// This attribute macro ensures that only the response body is automatically sent
3566/// to the client after the function completes, handling request headers separately.
3567///
3568/// # Usage
3569///
3570/// ```rust
3571/// use hyperlane::*;
3572/// use hyperlane_macros::*;
3573///
3574/// #[route("/send_body")]
3575/// struct SendBodyTest;
3576///
3577/// impl ServerHook for SendBodyTest {
3578/// async fn new(_ctx: &Context) -> Self {
3579/// Self
3580/// }
3581///
3582/// #[epilogue_macros(send_body)]
3583/// async fn handle(self, ctx: &Context) {}
3584/// }
3585///
3586/// impl SendBodyTest {
3587/// #[send_body]
3588/// async fn send_body_with_ref_self(&self, ctx: &Context) {}
3589/// }
3590///
3591/// #[send_body]
3592/// async fn standalone_send_body_handler(ctx: &Context) {}
3593/// ```
3594///
3595/// The macro takes no parameters and should be applied directly to async functions
3596/// that accept a `&Context` parameter.
3597///
3598/// # Panics
3599///
3600/// This macro will panic if the send body operation fails.
3601#[proc_macro_attribute]
3602pub fn send_body(_attr: TokenStream, item: TokenStream) -> TokenStream {
3603 send_body_macro(item, Position::Epilogue)
3604}
3605
3606/// Tries to send only the response body with data after function execution.
3607///
3608/// This attribute macro ensures that only the response body is automatically tried to be sent
3609/// to the client after the function completes, handling request headers separately,
3610/// with the specified data.
3611///
3612/// # Usage
3613///
3614/// ```rust
3615/// use hyperlane::*;
3616/// use hyperlane_macros::*;
3617///
3618/// #[route("/try_send_body_with_data")]
3619/// struct TrySendBodyWithData;
3620///
3621/// impl ServerHook for TrySendBodyWithData {
3622/// async fn new(_ctx: &Context) -> Self {
3623/// Self
3624/// }
3625///
3626/// #[epilogue_macros(try_send_body_with_data("Response body content"))]
3627/// async fn handle(self, ctx: &Context) {}
3628/// }
3629/// ```
3630///
3631/// The macro accepts data to send and should be applied to async functions
3632/// that accept a `&Context` parameter.
3633#[proc_macro_attribute]
3634pub fn try_send_body_with_data(attr: TokenStream, item: TokenStream) -> TokenStream {
3635 try_send_body_with_data_macro(attr, item, Position::Epilogue)
3636}
3637
3638/// Sends only the response body with data after function execution.
3639///
3640/// This attribute macro ensures that only the response body is automatically sent
3641/// to the client after the function completes, handling request headers separately,
3642/// with the specified data.
3643///
3644/// # Usage
3645///
3646/// ```rust
3647/// use hyperlane::*;
3648/// use hyperlane_macros::*;
3649///
3650/// #[route("/send_body_with_data")]
3651/// struct SendBodyWithData;
3652///
3653/// impl ServerHook for SendBodyWithData {
3654/// async fn new(_ctx: &Context) -> Self {
3655/// Self
3656/// }
3657///
3658/// #[epilogue_macros(send_body_with_data("Response body content"))]
3659/// async fn handle(self, ctx: &Context) {}
3660/// }
3661/// ```
3662///
3663/// The macro accepts data to send and should be applied to async functions
3664/// that accept a `&Context` parameter.
3665///
3666/// # Panics
3667///
3668/// This macro will panic if the send body with data operation fails.
3669#[proc_macro_attribute]
3670pub fn send_body_with_data(attr: TokenStream, item: TokenStream) -> TokenStream {
3671 send_body_with_data_macro(attr, item, Position::Epilogue)
3672}
3673
3674/// Tries to flush the response stream after function execution.
3675///
3676/// This attribute macro ensures that the response stream is tried to be flushed to guarantee immediate
3677/// data transmission, forcing any buffered response data to be sent to the client. This will not panic on failure.
3678///
3679/// # Usage
3680///
3681/// ```rust
3682/// use hyperlane::*;
3683/// use hyperlane_macros::*;
3684///
3685/// #[route("/try_flush")]
3686/// struct TryFlushTest;
3687///
3688/// impl ServerHook for TryFlushTest {
3689/// async fn new(_ctx: &Context) -> Self {
3690/// Self
3691/// }
3692///
3693/// #[epilogue_macros(try_flush)]
3694/// async fn handle(self, ctx: &Context) {}
3695/// }
3696///
3697/// impl TryFlushTest {
3698/// #[try_flush]
3699/// async fn try_flush_with_ref_self(&self, ctx: &Context) {}
3700/// }
3701///
3702/// #[try_flush]
3703/// async fn standalone_try_flush_handler(ctx: &Context) {}
3704/// ```
3705///
3706/// The macro takes no parameters and should be applied directly to async functions
3707/// that accept a `&Context` parameter.
3708#[proc_macro_attribute]
3709pub fn try_flush(_attr: TokenStream, item: TokenStream) -> TokenStream {
3710 try_flush_macro(item, Position::Prologue)
3711}
3712
3713/// Flushes the response stream after function execution.
3714///
3715/// This attribute macro ensures that the response stream is flushed to guarantee immediate
3716/// data transmission, forcing any buffered response data to be sent to the client.
3717///
3718/// # Usage
3719///
3720/// ```rust
3721/// use hyperlane::*;
3722/// use hyperlane_macros::*;
3723///
3724/// #[route("/flush")]
3725/// struct FlushTest;
3726///
3727/// impl ServerHook for FlushTest {
3728/// async fn new(_ctx: &Context) -> Self {
3729/// Self
3730/// }
3731///
3732/// #[epilogue_macros(flush)]
3733/// async fn handle(self, ctx: &Context) {}
3734/// }
3735///
3736/// impl FlushTest {
3737/// #[flush]
3738/// async fn flush_with_ref_self(&self, ctx: &Context) {}
3739/// }
3740///
3741/// #[flush]
3742/// async fn standalone_flush_handler(ctx: &Context) {}
3743/// ```
3744///
3745/// The macro takes no parameters and should be applied directly to async functions
3746/// that accept a `&Context` parameter.
3747///
3748/// # Panics
3749///
3750/// This macro will panic if the flush operation fails.
3751#[proc_macro_attribute]
3752pub fn flush(_attr: TokenStream, item: TokenStream) -> TokenStream {
3753 flush_macro(item, Position::Prologue)
3754}