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