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