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