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