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