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/// Sends the complete response exactly once after function execution.
917///
918/// This attribute macro ensures that the response is sent exactly once to the client,
919/// preventing multiple response transmissions for single-use scenarios.
920///
921/// # Usage
922///
923/// ```rust
924/// use hyperlane::*;
925/// use hyperlane_macros::*;
926///
927/// #[route("/send_once")]
928/// struct SendOnceTest;
929///
930/// impl ServerHook for SendOnceTest {
931/// async fn new(_ctx: &Context) -> Self {
932/// Self
933/// }
934///
935/// #[epilogue_macros(send_once)]
936/// async fn handle(self, ctx: &Context) {}
937/// }
938///
939/// impl SendOnceTest {
940/// #[send_once]
941/// async fn send_once_with_ref_self(&self, ctx: &Context) {}
942/// }
943///
944/// #[send_once]
945/// async fn standalone_send_once_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 send_once(_attr: TokenStream, item: TokenStream) -> TokenStream {
952 send_once_macro(item, Position::Epilogue)
953}
954
955/// Sends only the response body exactly once after function execution.
956///
957/// This attribute macro ensures that the response body is sent exactly once to the client,
958/// preventing multiple body transmissions for single-use scenarios.
959///
960/// # Usage
961///
962/// ```rust
963/// use hyperlane::*;
964/// use hyperlane_macros::*;
965///
966/// #[route("/send_body_once")]
967/// struct SendBodyOnceTest;
968///
969/// impl ServerHook for SendBodyOnceTest {
970/// async fn new(_ctx: &Context) -> Self {
971/// Self
972/// }
973///
974/// #[epilogue_macros(send_body_once)]
975/// async fn handle(self, ctx: &Context) {}
976/// }
977///
978/// impl SendBodyOnceTest {
979/// #[send_body_once]
980/// async fn send_body_once_with_ref_self(&self, ctx: &Context) {}
981/// }
982///
983/// #[send_body_once]
984/// async fn standalone_send_body_once_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 send_body_once(_attr: TokenStream, item: TokenStream) -> TokenStream {
991 send_body_once_macro(item, Position::Epilogue)
992}
993
994/// Sends the complete response exactly once with data after function execution.
995///
996/// This attribute macro ensures that the response is sent exactly once to the client,
997/// preventing multiple response transmissions for single-use scenarios, with the specified data.
998///
999/// # Usage
1000///
1001/// ```rust
1002/// use hyperlane::*;
1003/// use hyperlane_macros::*;
1004///
1005/// #[route("/send_once_with_data")]
1006/// struct SendOnceWithData;
1007///
1008/// impl ServerHook for SendOnceWithData {
1009/// async fn new(_ctx: &Context) -> Self {
1010/// Self
1011/// }
1012///
1013/// #[epilogue_macros(send_once_with_data("One-time response"))]
1014/// async fn handle(self, ctx: &Context) {}
1015/// }
1016///
1017/// impl SendOnceWithData {
1018/// #[send_once_with_data("One-time response")]
1019/// async fn send_once_with_data_with_ref_self(&self, ctx: &Context) {}
1020/// }
1021///
1022/// #[send_once_with_data("data")]
1023/// async fn standalone_send_once_with_data_handler(ctx: &Context) {}
1024/// ```
1025///
1026/// The macro accepts data to send and should be applied to async functions
1027/// that accept a `&Context` parameter.
1028#[proc_macro_attribute]
1029pub fn send_once_with_data(attr: TokenStream, item: TokenStream) -> TokenStream {
1030 send_once_with_data_macro(attr, item, Position::Epilogue)
1031}
1032
1033/// Flushes the response stream after function execution.
1034///
1035/// This attribute macro ensures that the response stream is flushed to guarantee immediate
1036/// data transmission, forcing any buffered response data to be sent to the client.
1037///
1038/// # Usage
1039///
1040/// ```rust
1041/// use hyperlane::*;
1042/// use hyperlane_macros::*;
1043///
1044/// #[route("/flush")]
1045/// struct FlushTest;
1046///
1047/// impl ServerHook for FlushTest {
1048/// async fn new(_ctx: &Context) -> Self {
1049/// Self
1050/// }
1051///
1052/// #[epilogue_macros(flush)]
1053/// async fn handle(self, ctx: &Context) {}
1054/// }
1055///
1056/// impl FlushTest {
1057/// #[flush]
1058/// async fn flush_with_ref_self(&self, ctx: &Context) {}
1059/// }
1060///
1061/// #[flush]
1062/// async fn standalone_flush_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 flush(_attr: TokenStream, item: TokenStream) -> TokenStream {
1069 flush_macro(item, Position::Prologue)
1070}
1071
1072/// Handles aborted request scenarios.
1073///
1074/// This attribute macro configures the function to handle cases where the client has
1075/// aborted the request, providing appropriate handling for interrupted or cancelled requests.
1076///
1077/// # Usage
1078///
1079/// ```rust
1080/// use hyperlane::*;
1081/// use hyperlane_macros::*;
1082///
1083/// #[route("/aborted")]
1084/// struct Aborted;
1085///
1086/// impl ServerHook for Aborted {
1087/// async fn new(_ctx: &Context) -> Self {
1088/// Self
1089/// }
1090///
1091/// #[aborted]
1092/// async fn handle(self, ctx: &Context) {}
1093/// }
1094///
1095/// impl Aborted {
1096/// #[aborted]
1097/// async fn aborted_with_ref_self(&self, ctx: &Context) {}
1098/// }
1099///
1100/// #[aborted]
1101/// async fn standalone_aborted_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 aborted(_attr: TokenStream, item: TokenStream) -> TokenStream {
1108 aborted_macro(item, Position::Prologue)
1109}
1110
1111/// Handles closed connection scenarios.
1112///
1113/// This attribute macro configures the function to handle cases where the connection
1114/// has been closed, providing appropriate handling for terminated or disconnected connections.
1115///
1116/// # Usage
1117///
1118/// ```rust
1119/// use hyperlane::*;
1120/// use hyperlane_macros::*;
1121///
1122/// #[route("/closed")]
1123/// struct ClosedTest;
1124///
1125/// impl ServerHook for ClosedTest {
1126/// async fn new(_ctx: &Context) -> Self {
1127/// Self
1128/// }
1129///
1130/// #[closed]
1131/// async fn handle(self, ctx: &Context) {}
1132/// }
1133///
1134/// impl ClosedTest {
1135/// #[closed]
1136/// async fn closed_with_ref_self(&self, ctx: &Context) {}
1137/// }
1138///
1139/// #[closed]
1140/// async fn standalone_closed_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 closed(_attr: TokenStream, item: TokenStream) -> TokenStream {
1147 closed_macro(item, Position::Prologue)
1148}
1149
1150/// Restricts function execution to HTTP/2 Cleartext (h2c) requests only.
1151///
1152/// This attribute macro ensures the decorated function only executes for HTTP/2 cleartext
1153/// requests that use the h2c upgrade mechanism.
1154///
1155/// # Usage
1156///
1157/// ```rust
1158/// use hyperlane::*;
1159/// use hyperlane_macros::*;
1160///
1161/// #[route("/h2c")]
1162/// struct H2c;
1163///
1164/// impl ServerHook for H2c {
1165/// async fn new(_ctx: &Context) -> Self {
1166/// Self
1167/// }
1168///
1169/// #[prologue_macros(h2c, response_body("h2c"))]
1170/// async fn handle(self, ctx: &Context) {}
1171/// }
1172///
1173/// impl H2c {
1174/// #[h2c]
1175/// async fn h2c_with_ref_self(&self, ctx: &Context) {}
1176/// }
1177///
1178/// #[h2c]
1179/// async fn standalone_h2c_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 h2c(_attr: TokenStream, item: TokenStream) -> TokenStream {
1186 h2c_macro(item, Position::Prologue)
1187}
1188
1189/// Restricts function execution to HTTP/0.9 requests only.
1190///
1191/// This attribute macro ensures the decorated function only executes for HTTP/0.9
1192/// protocol requests, the earliest version of the HTTP protocol.
1193///
1194/// # Usage
1195///
1196/// ```rust
1197/// use hyperlane::*;
1198/// use hyperlane_macros::*;
1199///
1200/// #[route("/http0_9")]
1201/// struct Http09;
1202///
1203/// impl ServerHook for Http09 {
1204/// async fn new(_ctx: &Context) -> Self {
1205/// Self
1206/// }
1207///
1208/// #[prologue_macros(http0_9, response_body("http0_9"))]
1209/// async fn handle(self, ctx: &Context) {}
1210/// }
1211///
1212/// impl Http09 {
1213/// #[http0_9]
1214/// async fn http0_9_with_ref_self(&self, ctx: &Context) {}
1215/// }
1216///
1217/// #[http0_9]
1218/// async fn standalone_http0_9_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 http0_9(_attr: TokenStream, item: TokenStream) -> TokenStream {
1225 http0_9_macro(item, Position::Prologue)
1226}
1227
1228/// Restricts function execution to HTTP/1.0 requests only.
1229///
1230/// This attribute macro ensures the decorated function only executes for HTTP/1.0
1231/// protocol requests.
1232///
1233/// # Usage
1234///
1235/// ```rust
1236/// use hyperlane::*;
1237/// use hyperlane_macros::*;
1238///
1239/// #[route("/http1_0")]
1240/// struct Http10;
1241///
1242/// impl ServerHook for Http10 {
1243/// async fn new(_ctx: &Context) -> Self {
1244/// Self
1245/// }
1246///
1247/// #[prologue_macros(http1_0, response_body("http1_0"))]
1248/// async fn handle(self, ctx: &Context) {}
1249/// }
1250///
1251/// impl Http10 {
1252/// #[http1_0]
1253/// async fn http1_0_with_ref_self(&self, ctx: &Context) {}
1254/// }
1255///
1256/// #[http1_0]
1257/// async fn standalone_http1_0_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 http1_0(_attr: TokenStream, item: TokenStream) -> TokenStream {
1264 http1_0_macro(item, Position::Prologue)
1265}
1266
1267/// Restricts function execution to HTTP/1.1 requests only.
1268///
1269/// This attribute macro ensures the decorated function only executes for HTTP/1.1
1270/// protocol requests.
1271///
1272/// # Usage
1273///
1274/// ```rust
1275/// use hyperlane::*;
1276/// use hyperlane_macros::*;
1277///
1278/// #[route("/http1_1")]
1279/// struct Http11;
1280///
1281/// impl ServerHook for Http11 {
1282/// async fn new(_ctx: &Context) -> Self {
1283/// Self
1284/// }
1285///
1286/// #[prologue_macros(http1_1, response_body("http1_1"))]
1287/// async fn handle(self, ctx: &Context) {}
1288/// }
1289///
1290/// impl Http11 {
1291/// #[http1_1]
1292/// async fn http1_1_with_ref_self(&self, ctx: &Context) {}
1293/// }
1294///
1295/// #[http1_1]
1296/// async fn standalone_http1_1_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 http1_1(_attr: TokenStream, item: TokenStream) -> TokenStream {
1303 http1_1_macro(item, Position::Prologue)
1304}
1305
1306/// Restricts function execution to HTTP/1.1 or higher protocol versions.
1307///
1308/// This attribute macro ensures the decorated function only executes for HTTP/1.1
1309/// or newer protocol versions, including HTTP/2, HTTP/3, and future versions.
1310///
1311/// # Usage
1312///
1313/// ```rust
1314/// use hyperlane::*;
1315/// use hyperlane_macros::*;
1316///
1317/// #[route("/http1_1_or_higher")]
1318/// struct Http11OrHigher;
1319///
1320/// impl ServerHook for Http11OrHigher {
1321/// async fn new(_ctx: &Context) -> Self {
1322/// Self
1323/// }
1324///
1325/// #[prologue_macros(http1_1_or_higher, response_body("http1_1_or_higher"))]
1326/// async fn handle(self, ctx: &Context) {}
1327/// }
1328///
1329/// impl Http11OrHigher {
1330/// #[http1_1_or_higher]
1331/// async fn http1_1_or_higher_with_ref_self(&self, ctx: &Context) {}
1332/// }
1333///
1334/// #[http1_1_or_higher]
1335/// async fn standalone_http1_1_or_higher_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 http1_1_or_higher(_attr: TokenStream, item: TokenStream) -> TokenStream {
1342 http1_1_or_higher_macro(item, Position::Prologue)
1343}
1344
1345/// Restricts function execution to HTTP/2 requests only.
1346///
1347/// This attribute macro ensures the decorated function only executes for HTTP/2
1348/// protocol requests.
1349///
1350/// # Usage
1351///
1352/// ```rust
1353/// use hyperlane::*;
1354/// use hyperlane_macros::*;
1355///
1356/// #[route("/http2")]
1357/// struct Http2;
1358///
1359/// impl ServerHook for Http2 {
1360/// async fn new(_ctx: &Context) -> Self {
1361/// Self
1362/// }
1363///
1364/// #[prologue_macros(http2, response_body("http2"))]
1365/// async fn handle(self, ctx: &Context) {}
1366/// }
1367///
1368/// impl Http2 {
1369/// #[http2]
1370/// async fn http2_with_ref_self(&self, ctx: &Context) {}
1371/// }
1372///
1373/// #[http2]
1374/// async fn standalone_http2_handler(ctx: &Context) {}
1375/// ```
1376///
1377/// The macro takes no parameters and should be applied directly to async functions
1378/// that accept a `&Context` parameter.
1379#[proc_macro_attribute]
1380pub fn http2(_attr: TokenStream, item: TokenStream) -> TokenStream {
1381 http2_macro(item, Position::Prologue)
1382}
1383
1384/// Restricts function execution to HTTP/3 requests only.
1385///
1386/// This attribute macro ensures the decorated function only executes for HTTP/3
1387/// protocol requests, the latest version of the HTTP protocol.
1388///
1389/// # Usage
1390///
1391/// ```rust
1392/// use hyperlane::*;
1393/// use hyperlane_macros::*;
1394///
1395/// #[route("/http3")]
1396/// struct Http3;
1397///
1398/// impl ServerHook for Http3 {
1399/// async fn new(_ctx: &Context) -> Self {
1400/// Self
1401/// }
1402///
1403/// #[prologue_macros(http3, response_body("http3"))]
1404/// async fn handle(self, ctx: &Context) {}
1405/// }
1406///
1407/// impl Http3 {
1408/// #[http3]
1409/// async fn http3_with_ref_self(&self, ctx: &Context) {}
1410/// }
1411///
1412/// #[http3]
1413/// async fn standalone_http3_handler(ctx: &Context) {}
1414/// ```
1415///
1416/// The macro takes no parameters and should be applied directly to async functions
1417/// that accept a `&Context` parameter.
1418#[proc_macro_attribute]
1419pub fn http3(_attr: TokenStream, item: TokenStream) -> TokenStream {
1420 http3_macro(item, Position::Prologue)
1421}
1422
1423/// Restricts function execution to TLS-encrypted requests only.
1424///
1425/// This attribute macro ensures the decorated function only executes for requests
1426/// that use TLS/SSL encryption on the connection.
1427///
1428/// # Usage
1429///
1430/// ```rust
1431/// use hyperlane::*;
1432/// use hyperlane_macros::*;
1433///
1434/// #[route("/tls")]
1435/// struct Tls;
1436///
1437/// impl ServerHook for Tls {
1438/// async fn new(_ctx: &Context) -> Self {
1439/// Self
1440/// }
1441///
1442/// #[prologue_macros(tls, response_body("tls"))]
1443/// async fn handle(self, ctx: &Context) {}
1444/// }
1445///
1446/// impl Tls {
1447/// #[tls]
1448/// async fn tls_with_ref_self(&self, ctx: &Context) {}
1449/// }
1450///
1451/// #[tls]
1452/// async fn standalone_tls_handler(ctx: &Context) {}
1453/// ```
1454///
1455/// The macro takes no parameters and should be applied directly to async functions
1456/// that accept a `&Context` parameter.
1457#[proc_macro_attribute]
1458pub fn tls(_attr: TokenStream, item: TokenStream) -> TokenStream {
1459 tls_macro(item, Position::Prologue)
1460}
1461
1462/// Filters requests based on a boolean condition.
1463///
1464/// The function continues execution only if the provided code block returns `true`.
1465///
1466/// # Usage
1467///
1468/// ```rust
1469/// use hyperlane::*;
1470/// use hyperlane_macros::*;
1471///
1472/// #[route("/unknown_method")]
1473/// struct UnknownMethod;
1474///
1475/// impl ServerHook for UnknownMethod {
1476/// async fn new(_ctx: &Context) -> Self {
1477/// Self
1478/// }
1479///
1480/// #[prologue_macros(
1481/// filter(ctx.get_request().await.is_unknown_method()),
1482/// response_body("unknown_method")
1483/// )]
1484/// async fn handle(self, ctx: &Context) {}
1485/// }
1486/// ```
1487#[proc_macro_attribute]
1488pub fn filter(attr: TokenStream, item: TokenStream) -> TokenStream {
1489 filter_macro(attr, item, Position::Prologue)
1490}
1491
1492/// Rejects requests based on a boolean condition.
1493///
1494/// The function continues execution only if the provided code block returns `false`.
1495///
1496/// # Usage
1497///
1498/// ```rust
1499/// use hyperlane::*;
1500/// use hyperlane_macros::*;
1501///
1502/// #[response_middleware(2)]
1503/// struct ResponseMiddleware2;
1504///
1505/// impl ServerHook for ResponseMiddleware2 {
1506/// async fn new(_ctx: &Context) -> Self {
1507/// Self
1508/// }
1509///
1510/// #[prologue_macros(
1511/// reject(ctx.get_request().await.is_ws())
1512/// )]
1513/// async fn handle(self, ctx: &Context) {}
1514/// }
1515/// ```
1516#[proc_macro_attribute]
1517pub fn reject(attr: TokenStream, item: TokenStream) -> TokenStream {
1518 reject_macro(attr, item, Position::Prologue)
1519}
1520
1521/// Restricts function execution to requests with a specific host.
1522///
1523/// This attribute macro ensures the decorated function only executes when the incoming request
1524/// has a host header that matches the specified value. Requests with different or missing host headers will be filtered out.
1525///
1526/// # Usage
1527///
1528/// ```rust
1529/// use hyperlane::*;
1530/// use hyperlane_macros::*;
1531///
1532/// #[route("/host")]
1533/// struct Host;
1534///
1535/// impl ServerHook for Host {
1536/// async fn new(_ctx: &Context) -> Self {
1537/// Self
1538/// }
1539///
1540/// #[host("localhost")]
1541/// #[prologue_macros(response_body("host string literal: localhost"), send)]
1542/// async fn handle(self, ctx: &Context) {}
1543/// }
1544///
1545/// impl Host {
1546/// #[host("localhost")]
1547/// async fn host_with_ref_self(&self, ctx: &Context) {}
1548/// }
1549///
1550/// #[host("localhost")]
1551/// async fn standalone_host_handler(ctx: &Context) {}
1552/// ```
1553///
1554/// The macro accepts a string literal specifying the expected host value and should be
1555/// applied to async functions that accept a `&Context` parameter.
1556#[proc_macro_attribute]
1557pub fn host(attr: TokenStream, item: TokenStream) -> TokenStream {
1558 host_macro(attr, item, Position::Prologue)
1559}
1560
1561/// Reject requests that have no host header.
1562///
1563/// This attribute macro ensures the decorated function only executes when the incoming request
1564/// has a host header present. Requests without a host header will be filtered out.
1565///
1566/// # Usage
1567///
1568/// ```rust
1569/// use hyperlane::*;
1570/// use hyperlane_macros::*;
1571///
1572/// #[route("/reject_host")]
1573/// struct RejectHost;
1574///
1575/// impl ServerHook for RejectHost {
1576/// async fn new(_ctx: &Context) -> Self {
1577/// Self
1578/// }
1579///
1580/// #[prologue_macros(
1581/// reject_host("filter.localhost"),
1582/// response_body("host filter string literal")
1583/// )]
1584/// async fn handle(self, ctx: &Context) {}
1585/// }
1586///
1587/// impl RejectHost {
1588/// #[reject_host("filter.localhost")]
1589/// async fn reject_host_with_ref_self(&self, ctx: &Context) {}
1590/// }
1591///
1592/// #[reject_host("filter.localhost")]
1593/// async fn standalone_reject_host_handler(ctx: &Context) {}
1594/// ```
1595///
1596/// The macro takes no parameters and should be applied directly to async functions
1597/// that accept a `&Context` parameter.
1598#[proc_macro_attribute]
1599pub fn reject_host(attr: TokenStream, item: TokenStream) -> TokenStream {
1600 reject_host_macro(attr, item, Position::Prologue)
1601}
1602
1603/// Restricts function execution to requests with a specific referer.
1604///
1605/// This attribute macro ensures the decorated function only executes when the incoming request
1606/// has a referer header that matches the specified value. Requests with different or missing referer headers will be filtered out.
1607///
1608/// # Usage
1609///
1610/// ```rust
1611/// use hyperlane::*;
1612/// use hyperlane_macros::*;
1613///
1614/// #[route("/referer")]
1615/// struct Referer;
1616///
1617/// impl ServerHook for Referer {
1618/// async fn new(_ctx: &Context) -> Self {
1619/// Self
1620/// }
1621///
1622/// #[prologue_macros(
1623/// referer("http://localhost"),
1624/// response_body("referer string literal: http://localhost")
1625/// )]
1626/// async fn handle(self, ctx: &Context) {}
1627/// }
1628///
1629/// impl Referer {
1630/// #[referer("http://localhost")]
1631/// async fn referer_with_ref_self(&self, ctx: &Context) {}
1632/// }
1633///
1634/// #[referer("http://localhost")]
1635/// async fn standalone_referer_handler(ctx: &Context) {}
1636/// ```
1637///
1638/// The macro accepts a string literal specifying the expected referer value and should be
1639/// applied to async functions that accept a `&Context` parameter.
1640#[proc_macro_attribute]
1641pub fn referer(attr: TokenStream, item: TokenStream) -> TokenStream {
1642 referer_macro(attr, item, Position::Prologue)
1643}
1644
1645/// Reject requests that have a specific referer header.
1646///
1647/// This attribute macro ensures the decorated function only executes when the incoming request
1648/// does not have a referer header that matches the specified value. Requests with the matching referer header will be filtered out.
1649///
1650/// # Usage
1651///
1652/// ```rust
1653/// use hyperlane::*;
1654/// use hyperlane_macros::*;
1655///
1656/// #[route("/reject_referer")]
1657/// struct RejectReferer;
1658///
1659/// impl ServerHook for RejectReferer {
1660/// async fn new(_ctx: &Context) -> Self {
1661/// Self
1662/// }
1663///
1664/// #[prologue_macros(
1665/// reject_referer("http://localhost"),
1666/// response_body("referer filter string literal")
1667/// )]
1668/// async fn handle(self, ctx: &Context) {}
1669/// }
1670///
1671/// impl RejectReferer {
1672/// #[reject_referer("http://localhost")]
1673/// async fn reject_referer_with_ref_self(&self, ctx: &Context) {}
1674/// }
1675///
1676/// #[reject_referer("http://localhost")]
1677/// async fn standalone_reject_referer_handler(ctx: &Context) {}
1678/// ```
1679///
1680/// The macro accepts a string literal specifying the referer value to filter out and should be
1681/// applied to async functions that accept a `&Context` parameter.
1682#[proc_macro_attribute]
1683pub fn reject_referer(attr: TokenStream, item: TokenStream) -> TokenStream {
1684 reject_referer_macro(attr, item, Position::Prologue)
1685}
1686
1687/// Executes multiple specified functions before the main handler function.
1688///
1689/// This attribute macro configures multiple pre-execution hooks that run before the main function logic.
1690/// The specified hook functions will be called in the order provided, followed by the main function execution.
1691///
1692/// # Usage
1693///
1694/// ```rust
1695/// use hyperlane::*;
1696/// use hyperlane_macros::*;
1697///
1698/// struct PrologueHooks;
1699///
1700/// impl ServerHook for PrologueHooks {
1701/// async fn new(_ctx: &Context) -> Self {
1702/// Self
1703/// }
1704///
1705/// #[get]
1706/// #[http]
1707/// async fn handle(self, _ctx: &Context) {}
1708/// }
1709///
1710/// async fn prologue_hooks_fn(ctx: Context) {
1711/// let hook = PrologueHooks::new(&ctx).await;
1712/// hook.handle(&ctx).await;
1713/// }
1714///
1715/// #[route("/hook")]
1716/// struct Hook;
1717///
1718/// impl ServerHook for Hook {
1719/// async fn new(_ctx: &Context) -> Self {
1720/// Self
1721/// }
1722///
1723/// #[prologue_hooks(prologue_hooks_fn)]
1724/// #[response_body("Testing hook macro")]
1725/// async fn handle(self, ctx: &Context) {}
1726/// }
1727/// ```
1728///
1729/// The macro accepts a comma-separated list of function names as parameters. All hook functions
1730/// and the main function must accept a `Context` parameter. Avoid combining this macro with other
1731/// macros on the same function to prevent macro expansion conflicts.
1732#[proc_macro_attribute]
1733pub fn prologue_hooks(attr: TokenStream, item: TokenStream) -> TokenStream {
1734 prologue_hooks_macro(attr, item, Position::Prologue)
1735}
1736
1737/// Executes multiple specified functions after the main handler function.
1738///
1739/// This attribute macro configures multiple post-execution hooks that run after the main function logic.
1740/// The main function will execute first, followed by the specified hook functions in the order provided.
1741///
1742/// # Usage
1743///
1744/// ```rust
1745/// use hyperlane::*;
1746/// use hyperlane_macros::*;
1747///
1748/// struct EpilogueHooks;
1749///
1750/// impl ServerHook for EpilogueHooks {
1751/// async fn new(_ctx: &Context) -> Self {
1752/// Self
1753/// }
1754///
1755/// #[response_status_code(200)]
1756/// async fn handle(self, ctx: &Context) {}
1757/// }
1758///
1759/// async fn epilogue_hooks_fn(ctx: Context) {
1760/// let hook = EpilogueHooks::new(&ctx).await;
1761/// hook.handle(&ctx).await;
1762/// }
1763///
1764/// #[route("/hook")]
1765/// struct Hook;
1766///
1767/// impl ServerHook for Hook {
1768/// async fn new(_ctx: &Context) -> Self {
1769/// Self
1770/// }
1771///
1772/// #[epilogue_hooks(epilogue_hooks_fn)]
1773/// #[response_body("Testing hook macro")]
1774/// async fn handle(self, ctx: &Context) {}
1775/// }
1776/// ```
1777///
1778/// The macro accepts a comma-separated list of function names as parameters. All hook functions
1779/// and the main function must accept a `Context` parameter. Avoid combining this macro with other
1780/// macros on the same function to prevent macro expansion conflicts.
1781#[proc_macro_attribute]
1782pub fn epilogue_hooks(attr: TokenStream, item: TokenStream) -> TokenStream {
1783 epilogue_hooks_macro(attr, item, Position::Epilogue)
1784}
1785
1786/// Extracts the raw request body into a specified variable.
1787///
1788/// This attribute macro extracts the raw request body content into a variable
1789/// with the fixed type `RequestBody`. The body content is not parsed or deserialized.
1790///
1791/// # Usage
1792///
1793/// ```rust
1794/// use hyperlane::*;
1795/// use hyperlane_macros::*;
1796///
1797/// #[route("/request_body")]
1798/// struct RequestBodyRoute;
1799///
1800/// impl ServerHook for RequestBodyRoute {
1801/// async fn new(_ctx: &Context) -> Self {
1802/// Self
1803/// }
1804///
1805/// #[response_body(&format!("raw body: {raw_body:?}"))]
1806/// #[request_body(raw_body)]
1807/// async fn handle(self, ctx: &Context) {}
1808/// }
1809///
1810/// impl RequestBodyRoute {
1811/// #[request_body(raw_body)]
1812/// async fn request_body_with_ref_self(&self, ctx: &Context) {}
1813/// }
1814///
1815/// #[request_body(raw_body)]
1816/// async fn standalone_request_body_handler(ctx: &Context) {}
1817/// ```
1818///
1819/// # Multi-Parameter Usage
1820///
1821/// ```rust
1822/// use hyperlane::*;
1823/// use hyperlane_macros::*;
1824///
1825/// #[route("/multi_body")]
1826/// struct MultiBody;
1827///
1828/// impl ServerHook for MultiBody {
1829/// async fn new(_ctx: &Context) -> Self {
1830/// Self
1831/// }
1832///
1833/// #[response_body(&format!("bodies: {body1:?}, {body2:?}"))]
1834/// #[request_body(body1, body2)]
1835/// async fn handle(self, ctx: &Context) {}
1836/// }
1837/// ```
1838///
1839/// The macro accepts one or more variable names separated by commas.
1840/// Each variable will be available in the function scope as a `RequestBody` type.
1841#[proc_macro_attribute]
1842pub fn request_body(attr: TokenStream, item: TokenStream) -> TokenStream {
1843 request_body_macro(attr, item, Position::Prologue)
1844}
1845
1846/// Parses the request body as JSON into a specified variable and type.
1847///
1848/// This attribute macro extracts and deserializes the request body content as JSON into a variable
1849/// with the specified type. The body content is parsed as JSON using serde.
1850///
1851/// # Usage
1852///
1853/// ```rust
1854/// use hyperlane::*;
1855/// use hyperlane_macros::*;
1856/// use serde::{Deserialize, Serialize};
1857///
1858/// #[derive(Debug, Serialize, Deserialize, Clone)]
1859/// struct TestData {
1860/// name: String,
1861/// age: u32,
1862/// }
1863///
1864/// #[route("/request_body_json")]
1865/// struct RequestBodyJson;
1866///
1867/// impl ServerHook for RequestBodyJson {
1868/// async fn new(_ctx: &Context) -> Self {
1869/// Self
1870/// }
1871///
1872/// #[response_body(&format!("request data: {request_data_result:?}"))]
1873/// #[request_body_json(request_data_result: TestData)]
1874/// async fn handle(self, ctx: &Context) {}
1875/// }
1876///
1877/// impl RequestBodyJson {
1878/// #[request_body_json(request_data_result: TestData)]
1879/// async fn request_body_json_with_ref_self(&self, ctx: &Context) {}
1880/// }
1881///
1882/// #[request_body_json(request_data_result: TestData)]
1883/// async fn standalone_request_body_json_handler(ctx: &Context) {}
1884/// ```
1885///
1886/// # Multi-Parameter Usage
1887///
1888/// ```rust
1889/// use hyperlane::*;
1890/// use hyperlane_macros::*;
1891/// use serde::{Deserialize, Serialize};
1892///
1893/// #[derive(Debug, Serialize, Deserialize, Clone)]
1894/// struct User {
1895/// name: String,
1896/// }
1897///
1898/// #[derive(Debug, Serialize, Deserialize, Clone)]
1899/// struct Config {
1900/// debug: bool,
1901/// }
1902///
1903/// #[route("/multi_json")]
1904/// struct MultiJson;
1905///
1906/// impl ServerHook for MultiJson {
1907/// async fn new(_ctx: &Context) -> Self {
1908/// Self
1909/// }
1910///
1911/// #[response_body(&format!("user: {user:?}, config: {config:?}"))]
1912/// #[request_body_json(user: User, config: Config)]
1913/// async fn handle(self, ctx: &Context) {}
1914/// }
1915/// ```
1916///
1917/// The macro accepts one or more `variable_name: Type` pairs separated by commas.
1918/// Each variable will be available in the function scope as a `Result<Type, JsonError>`.
1919#[proc_macro_attribute]
1920pub fn request_body_json(attr: TokenStream, item: TokenStream) -> TokenStream {
1921 request_body_json_macro(attr, item, Position::Prologue)
1922}
1923
1924/// Extracts a specific attribute value into a variable.
1925///
1926/// This attribute macro retrieves a specific attribute by key and makes it available
1927/// as a typed variable from the request context.
1928///
1929/// # Usage
1930///
1931/// ```rust
1932/// use hyperlane::*;
1933/// use hyperlane_macros::*;
1934/// use serde::{Deserialize, Serialize};
1935///
1936/// const TEST_ATTRIBUTE_KEY: &str = "test_attribute_key";
1937///
1938/// #[derive(Debug, Serialize, Deserialize, Clone)]
1939/// struct TestData {
1940/// name: String,
1941/// age: u32,
1942/// }
1943///
1944/// #[route("/attribute")]
1945/// struct Attribute;
1946///
1947/// impl ServerHook for Attribute {
1948/// async fn new(_ctx: &Context) -> Self {
1949/// Self
1950/// }
1951///
1952/// #[response_body(&format!("request attribute: {request_attribute_option:?}"))]
1953/// #[attribute(TEST_ATTRIBUTE_KEY => request_attribute_option: TestData)]
1954/// async fn handle(self, ctx: &Context) {}
1955/// }
1956///
1957/// impl Attribute {
1958/// #[attribute(TEST_ATTRIBUTE_KEY => request_attribute_option: TestData)]
1959/// async fn attribute_with_ref_self(&self, ctx: &Context) {}
1960/// }
1961///
1962/// #[attribute(TEST_ATTRIBUTE_KEY => request_attribute_option: TestData)]
1963/// async fn standalone_attribute_handler(ctx: &Context) {}
1964/// ```
1965///
1966/// The macro accepts a key-to-variable mapping in the format `key => variable_name: Type`.
1967/// The variable will be available as an `Option<Type>` in the function scope.
1968///
1969/// # Multi-Parameter Usage
1970///
1971/// ```rust
1972/// use hyperlane::*;
1973/// use hyperlane_macros::*;
1974///
1975/// #[route("/multi_attr")]
1976/// struct MultiAttr;
1977///
1978/// impl ServerHook for MultiAttr {
1979/// async fn new(_ctx: &Context) -> Self {
1980/// Self
1981/// }
1982///
1983/// #[response_body(&format!("attrs: {attr1:?}, {attr2:?}"))]
1984/// #[attribute("key1" => attr1: String, "key2" => attr2: i32)]
1985/// async fn handle(self, ctx: &Context) {}
1986/// }
1987/// ```
1988///
1989/// The macro accepts multiple `key => variable_name: Type` tuples separated by commas.
1990#[proc_macro_attribute]
1991pub fn attribute(attr: TokenStream, item: TokenStream) -> TokenStream {
1992 attribute_macro(attr, item, Position::Prologue)
1993}
1994
1995/// Extracts all attributes into a HashMap variable.
1996///
1997/// This attribute macro retrieves all available attributes from the request context
1998/// and makes them available as a HashMap for comprehensive attribute access.
1999///
2000/// # Usage
2001///
2002/// ```rust
2003/// use hyperlane::*;
2004/// use hyperlane_macros::*;
2005///
2006/// #[route("/attributes")]
2007/// struct Attributes;
2008///
2009/// impl ServerHook for Attributes {
2010/// async fn new(_ctx: &Context) -> Self {
2011/// Self
2012/// }
2013///
2014/// #[response_body(&format!("request attributes: {request_attributes:?}"))]
2015/// #[attributes(request_attributes)]
2016/// async fn handle(self, ctx: &Context) {}
2017/// }
2018///
2019/// impl Attributes {
2020/// #[attributes(request_attributes)]
2021/// async fn attributes_with_ref_self(&self, ctx: &Context) {}
2022/// }
2023///
2024/// #[attributes(request_attributes)]
2025/// async fn standalone_attributes_handler(ctx: &Context) {}
2026/// ```
2027///
2028/// The macro accepts a variable name that will contain a HashMap of all attributes.
2029/// The variable will be available as a HashMap in the function scope.
2030///
2031/// # Multi-Parameter Usage
2032///
2033/// ```rust
2034/// use hyperlane::*;
2035/// use hyperlane_macros::*;
2036///
2037/// #[route("/multi_attrs")]
2038/// struct MultiAttrs;
2039///
2040/// impl ServerHook for MultiAttrs {
2041/// async fn new(_ctx: &Context) -> Self {
2042/// Self
2043/// }
2044///
2045/// #[response_body(&format!("attrs1: {attrs1:?}, attrs2: {attrs2:?}"))]
2046/// #[attributes(attrs1, attrs2)]
2047/// async fn handle(self, ctx: &Context) {}
2048/// }
2049/// ```
2050///
2051/// The macro accepts multiple variable names separated by commas.
2052#[proc_macro_attribute]
2053pub fn attributes(attr: TokenStream, item: TokenStream) -> TokenStream {
2054 attributes_macro(attr, item, Position::Prologue)
2055}
2056
2057/// Extracts a specific route parameter into a variable.
2058///
2059/// This attribute macro retrieves a specific route parameter by key and makes it
2060/// available as a variable. Route parameters are extracted from the URL path segments.
2061///
2062/// # Usage
2063///
2064/// ```rust
2065/// use hyperlane::*;
2066/// use hyperlane_macros::*;
2067///
2068/// #[route("/route_param/:test")]
2069/// struct RouteParam;
2070///
2071/// impl ServerHook for RouteParam {
2072/// async fn new(_ctx: &Context) -> Self {
2073/// Self
2074/// }
2075///
2076/// #[response_body(&format!("route param: {request_route_param:?}"))]
2077/// #[route_param("test" => request_route_param)]
2078/// async fn handle(self, ctx: &Context) {}
2079/// }
2080///
2081/// impl RouteParam {
2082/// #[route_param("test" => request_route_param)]
2083/// async fn route_param_with_ref_self(&self, ctx: &Context) {}
2084/// }
2085///
2086/// #[route_param("test" => request_route_param)]
2087/// async fn standalone_route_param_handler(ctx: &Context) {}
2088/// ```
2089///
2090/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
2091/// The variable will be available as an `Option<String>` in the function scope.
2092///
2093/// # Multi-Parameter Usage
2094///
2095/// ```rust
2096/// use hyperlane::*;
2097/// use hyperlane_macros::*;
2098///
2099/// #[route("/multi_param/:id/:name")]
2100/// struct MultiParam;
2101///
2102/// impl ServerHook for MultiParam {
2103/// async fn new(_ctx: &Context) -> Self {
2104/// Self
2105/// }
2106///
2107/// #[response_body(&format!("id: {id:?}, name: {name:?}"))]
2108/// #[route_param("id" => id, "name" => name)]
2109/// async fn handle(self, ctx: &Context) {}
2110/// }
2111/// ```
2112///
2113/// The macro accepts multiple `"key" => variable_name` pairs separated by commas.
2114#[proc_macro_attribute]
2115pub fn route_param(attr: TokenStream, item: TokenStream) -> TokenStream {
2116 route_param_macro(attr, item, Position::Prologue)
2117}
2118
2119/// Extracts all route parameters into a collection variable.
2120///
2121/// This attribute macro retrieves all available route parameters from the URL path
2122/// and makes them available as a collection for comprehensive route parameter access.
2123///
2124/// # Usage
2125///
2126/// ```rust
2127/// use hyperlane::*;
2128/// use hyperlane_macros::*;
2129///
2130/// #[route("/route_params/:test")]
2131/// struct RouteParams;
2132///
2133/// impl ServerHook for RouteParams {
2134/// async fn new(_ctx: &Context) -> Self {
2135/// Self
2136/// }
2137///
2138/// #[response_body(&format!("request route params: {request_route_params:?}"))]
2139/// #[route_params(request_route_params)]
2140/// async fn handle(self, ctx: &Context) {}
2141/// }
2142///
2143/// impl RouteParams {
2144/// #[route_params(request_route_params)]
2145/// async fn route_params_with_ref_self(&self, ctx: &Context) {}
2146/// }
2147///
2148/// #[route_params(request_route_params)]
2149/// async fn standalone_route_params_handler(ctx: &Context) {}
2150/// ```
2151///
2152/// The macro accepts a variable name that will contain all route parameters.
2153/// The variable will be available as a collection in the function scope.
2154///
2155/// # Multi-Parameter Usage
2156///
2157/// ```rust
2158/// use hyperlane::*;
2159/// use hyperlane_macros::*;
2160///
2161/// #[route("/multi_params/:id")]
2162/// struct MultiParams;
2163///
2164/// impl ServerHook for MultiParams {
2165/// async fn new(_ctx: &Context) -> Self {
2166/// Self
2167/// }
2168///
2169/// #[response_body(&format!("params1: {params1:?}, params2: {params2:?}"))]
2170/// #[route_params(params1, params2)]
2171/// async fn handle(self, ctx: &Context) {}
2172/// }
2173/// ```
2174///
2175/// The macro accepts multiple variable names separated by commas.
2176#[proc_macro_attribute]
2177pub fn route_params(attr: TokenStream, item: TokenStream) -> TokenStream {
2178 route_params_macro(attr, item, Position::Prologue)
2179}
2180
2181/// Extracts a specific request query parameter into a variable.
2182///
2183/// This attribute macro retrieves a specific request query parameter by key and makes it
2184/// available as a variable. Query parameters are extracted from the URL request query string.
2185///
2186/// # Usage
2187///
2188/// ```rust
2189/// use hyperlane::*;
2190/// use hyperlane_macros::*;
2191///
2192/// #[route("/request_query")]
2193/// struct RequestQuery;
2194///
2195/// impl ServerHook for RequestQuery {
2196/// async fn new(_ctx: &Context) -> Self {
2197/// Self
2198/// }
2199///
2200/// #[prologue_macros(
2201/// request_query("test" => request_query_option),
2202/// response_body(&format!("request query: {request_query_option:?}")),
2203/// send
2204/// )]
2205/// async fn handle(self, ctx: &Context) {}
2206/// }
2207///
2208/// impl RequestQuery {
2209/// #[request_query("test" => request_query_option)]
2210/// async fn request_query_with_ref_self(&self, ctx: &Context) {}
2211/// }
2212///
2213/// #[request_query("test" => request_query_option)]
2214/// async fn standalone_request_query_handler(ctx: &Context) {}
2215/// ```
2216///
2217/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
2218/// The variable will be available as an `Option<String>` in the function scope.
2219///
2220/// Supports multiple parameters: `#[request_query("k1" => v1, "k2" => v2)]`
2221#[proc_macro_attribute]
2222pub fn request_query(attr: TokenStream, item: TokenStream) -> TokenStream {
2223 request_query_macro(attr, item, Position::Prologue)
2224}
2225
2226/// Extracts all request query parameters into a collection variable.
2227///
2228/// This attribute macro retrieves all available request query parameters from the URL request query string
2229/// and makes them available as a collection for comprehensive request query parameter access.
2230///
2231/// # Usage
2232///
2233/// ```rust
2234/// use hyperlane::*;
2235/// use hyperlane_macros::*;
2236///
2237/// #[route("/request_querys")]
2238/// struct RequestQuerys;
2239///
2240/// impl ServerHook for RequestQuerys {
2241/// async fn new(_ctx: &Context) -> Self {
2242/// Self
2243/// }
2244///
2245/// #[prologue_macros(
2246/// request_querys(request_querys),
2247/// response_body(&format!("request querys: {request_querys:?}")),
2248/// send
2249/// )]
2250/// async fn handle(self, ctx: &Context) {}
2251/// }
2252///
2253/// impl RequestQuerys {
2254/// #[request_querys(request_querys)]
2255/// async fn request_querys_with_ref_self(&self, ctx: &Context) {}
2256/// }
2257///
2258/// #[request_querys(request_querys)]
2259/// async fn standalone_request_querys_handler(ctx: &Context) {}
2260/// ```
2261///
2262/// The macro accepts a variable name that will contain all request query parameters.
2263/// The variable will be available as a collection in the function scope.
2264///
2265/// Supports multiple parameters: `#[request_querys(querys1, querys2)]`
2266#[proc_macro_attribute]
2267pub fn request_querys(attr: TokenStream, item: TokenStream) -> TokenStream {
2268 request_querys_macro(attr, item, Position::Prologue)
2269}
2270
2271/// Extracts a specific HTTP request header into a variable.
2272///
2273/// This attribute macro retrieves a specific HTTP request header by name and makes it
2274/// available as a variable. Header values are extracted from the request request headers collection.
2275///
2276/// # Usage
2277///
2278/// ```rust
2279/// use hyperlane::*;
2280/// use hyperlane_macros::*;
2281///
2282/// #[route("/request_header")]
2283/// struct RequestHeader;
2284///
2285/// impl ServerHook for RequestHeader {
2286/// async fn new(_ctx: &Context) -> Self {
2287/// Self
2288/// }
2289///
2290/// #[prologue_macros(
2291/// request_header(HOST => request_header_option),
2292/// response_body(&format!("request header: {request_header_option:?}")),
2293/// send
2294/// )]
2295/// async fn handle(self, ctx: &Context) {}
2296/// }
2297///
2298/// impl RequestHeader {
2299/// #[request_header(HOST => request_header_option)]
2300/// async fn request_header_with_ref_self(&self, ctx: &Context) {}
2301/// }
2302///
2303/// #[request_header(HOST => request_header_option)]
2304/// async fn standalone_request_header_handler(ctx: &Context) {}
2305/// ```
2306///
2307/// The macro accepts a request header name-to-variable mapping in the format `HEADER_NAME => variable_name`
2308/// or `"Header-Name" => variable_name`. The variable will be available as an `Option<String>`.
2309#[proc_macro_attribute]
2310pub fn request_header(attr: TokenStream, item: TokenStream) -> TokenStream {
2311 request_header_macro(attr, item, Position::Prologue)
2312}
2313
2314/// Extracts all HTTP request headers into a collection variable.
2315///
2316/// This attribute macro retrieves all available HTTP request headers from the request
2317/// and makes them available as a collection for comprehensive request header access.
2318///
2319/// # Usage
2320///
2321/// ```rust
2322/// use hyperlane::*;
2323/// use hyperlane_macros::*;
2324///
2325/// #[route("/request_headers")]
2326/// struct RequestHeaders;
2327///
2328/// impl ServerHook for RequestHeaders {
2329/// async fn new(_ctx: &Context) -> Self {
2330/// Self
2331/// }
2332///
2333/// #[prologue_macros(
2334/// request_headers(request_headers),
2335/// response_body(&format!("request headers: {request_headers:?}")),
2336/// send
2337/// )]
2338/// async fn handle(self, ctx: &Context) {}
2339/// }
2340///
2341/// impl RequestHeaders {
2342/// #[request_headers(request_headers)]
2343/// async fn request_headers_with_ref_self(&self, ctx: &Context) {}
2344/// }
2345///
2346/// #[request_headers(request_headers)]
2347/// async fn standalone_request_headers_handler(ctx: &Context) {}
2348/// ```
2349///
2350/// The macro accepts a variable name that will contain all HTTP request headers.
2351/// The variable will be available as a collection in the function scope.
2352#[proc_macro_attribute]
2353pub fn request_headers(attr: TokenStream, item: TokenStream) -> TokenStream {
2354 request_headers_macro(attr, item, Position::Prologue)
2355}
2356
2357/// Extracts a specific cookie value or all cookies into a variable.
2358///
2359/// This attribute macro supports two syntaxes:
2360/// 1. `cookie(key => variable_name)` - Extract a specific cookie value by key
2361/// 2. `cookie(variable_name)` - Extract all cookies as a raw string
2362///
2363/// # Usage
2364///
2365/// ```rust
2366/// use hyperlane::*;
2367/// use hyperlane_macros::*;
2368///
2369/// #[route("/cookie")]
2370/// struct Cookie;
2371///
2372/// impl ServerHook for Cookie {
2373/// async fn new(_ctx: &Context) -> Self {
2374/// Self
2375/// }
2376///
2377/// #[response_body(&format!("Session cookie: {session_cookie_opt:?}"))]
2378/// #[request_cookie("test" => session_cookie_opt)]
2379/// async fn handle(self, ctx: &Context) {}
2380/// }
2381///
2382/// impl Cookie {
2383/// #[request_cookie("test" => session_cookie_opt)]
2384/// async fn request_cookie_with_ref_self(&self, ctx: &Context) {}
2385/// }
2386///
2387/// #[request_cookie("test" => session_cookie_opt)]
2388/// async fn standalone_request_cookie_handler(ctx: &Context) {}
2389/// ```
2390///
2391/// For specific cookie extraction, the variable will be available as `Option<String>`.
2392/// For all cookies extraction, the variable will be available as `String`.
2393#[proc_macro_attribute]
2394pub fn request_cookie(attr: TokenStream, item: TokenStream) -> TokenStream {
2395 request_cookie_macro(attr, item, Position::Prologue)
2396}
2397
2398/// Extracts all cookies as a raw string into a variable.
2399///
2400/// This attribute macro retrieves the entire Cookie header from the request and makes it
2401/// available as a String variable. If no Cookie header is present, an empty string is used.
2402///
2403/// # Usage
2404///
2405/// ```rust
2406/// use hyperlane::*;
2407/// use hyperlane_macros::*;
2408///
2409/// #[route("/cookies")]
2410/// struct Cookies;
2411///
2412/// impl ServerHook for Cookies {
2413/// async fn new(_ctx: &Context) -> Self {
2414/// Self
2415/// }
2416///
2417/// #[response_body(&format!("All cookies: {cookie_value:?}"))]
2418/// #[request_cookies(cookie_value)]
2419/// async fn handle(self, ctx: &Context) {}
2420/// }
2421///
2422/// impl Cookies {
2423/// #[request_cookies(cookie_value)]
2424/// async fn request_cookies_with_ref_self(&self, ctx: &Context) {}
2425/// }
2426///
2427/// #[request_cookies(cookie_value)]
2428/// async fn standalone_request_cookies_handler(ctx: &Context) {}
2429/// ```
2430///
2431/// The macro accepts a variable name that will contain the Cookie header value.
2432/// The variable will be available as a String in the function scope.
2433#[proc_macro_attribute]
2434pub fn request_cookies(attr: TokenStream, item: TokenStream) -> TokenStream {
2435 request_cookies_macro(attr, item, Position::Prologue)
2436}
2437
2438/// Extracts the HTTP request version into a variable.
2439///
2440/// This attribute macro retrieves the HTTP version from the request and makes it
2441/// available as a variable. The version represents the HTTP protocol version used.
2442///
2443/// # Usage
2444///
2445/// ```rust
2446/// use hyperlane::*;
2447/// use hyperlane_macros::*;
2448///
2449/// #[route("/request_version")]
2450/// struct RequestVersionTest;
2451///
2452/// impl ServerHook for RequestVersionTest {
2453/// async fn new(_ctx: &Context) -> Self {
2454/// Self
2455/// }
2456///
2457/// #[response_body(&format!("HTTP Version: {http_version}"))]
2458/// #[request_version(http_version)]
2459/// async fn handle(self, ctx: &Context) {}
2460/// }
2461///
2462/// impl RequestVersionTest {
2463/// #[request_version(http_version)]
2464/// async fn request_version_with_ref_self(&self, ctx: &Context) {}
2465/// }
2466///
2467/// #[request_version(http_version)]
2468/// async fn standalone_request_version_handler(ctx: &Context) {}
2469/// ```
2470///
2471/// The macro accepts a variable name that will contain the HTTP request version.
2472/// The variable will be available as a RequestVersion type in the function scope.
2473#[proc_macro_attribute]
2474pub fn request_version(attr: TokenStream, item: TokenStream) -> TokenStream {
2475 request_version_macro(attr, item, Position::Prologue)
2476}
2477
2478/// Extracts the HTTP request path into a variable.
2479///
2480/// This attribute macro retrieves the request path from the HTTP request and makes it
2481/// available as a variable. The path represents the URL path portion of the request.
2482///
2483/// # Usage
2484///
2485/// ```rust
2486/// use hyperlane::*;
2487/// use hyperlane_macros::*;
2488///
2489/// #[route("/request_path")]
2490/// struct RequestPathTest;
2491///
2492/// impl ServerHook for RequestPathTest {
2493/// async fn new(_ctx: &Context) -> Self {
2494/// Self
2495/// }
2496///
2497/// #[response_body(&format!("Request Path: {request_path}"))]
2498/// #[request_path(request_path)]
2499/// async fn handle(self, ctx: &Context) {}
2500/// }
2501///
2502/// impl RequestPathTest {
2503/// #[request_path(request_path)]
2504/// async fn request_path_with_ref_self(&self, ctx: &Context) {}
2505/// }
2506///
2507/// #[request_path(request_path)]
2508/// async fn standalone_request_path_handler(ctx: &Context) {}
2509/// ```
2510///
2511/// The macro accepts a variable name that will contain the HTTP request path.
2512/// The variable will be available as a RequestPath type in the function scope.
2513#[proc_macro_attribute]
2514pub fn request_path(attr: TokenStream, item: TokenStream) -> TokenStream {
2515 request_path_macro(attr, item, Position::Prologue)
2516}
2517
2518/// Creates a new instance of a specified type with a given variable name.
2519///
2520/// This attribute macro generates an instance initialization at the beginning of the function.
2521///
2522/// # Usage
2523///
2524/// ```rust,no_run
2525/// use hyperlane::*;
2526/// use hyperlane_macros::*;
2527///
2528/// #[hyperlane(server: Server)]
2529/// #[hyperlane(config: ServerConfig)]
2530/// #[tokio::main]
2531/// async fn main() {
2532/// config.disable_nodelay().await;
2533/// server.config(config).await;
2534/// let server_hook: ServerControlHook = server.run().await.unwrap_or_default();
2535/// server_hook.wait().await;
2536/// }
2537/// ```
2538///
2539/// The macro accepts a `variable_name: Type` pair.
2540/// The variable will be available as an instance of the specified type in the function scope.
2541#[proc_macro_attribute]
2542pub fn hyperlane(attr: TokenStream, item: TokenStream) -> TokenStream {
2543 hyperlane_macro(attr, item)
2544}
2545
2546/// Registers a function as a route handler.
2547///
2548/// This attribute macro registers the decorated function as a route handler for a given path.
2549/// This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
2550///
2551/// # Usage
2552///
2553/// ```rust
2554/// use hyperlane::*;
2555/// use hyperlane_macros::*;
2556///
2557/// #[route("/response")]
2558/// struct Response;
2559///
2560/// impl ServerHook for Response {
2561/// async fn new(_ctx: &Context) -> Self {
2562/// Self
2563/// }
2564///
2565/// #[response_body("response")]
2566/// async fn handle(self, ctx: &Context) {}
2567/// }
2568/// ```
2569///
2570/// # Parameters
2571///
2572/// - `path`: String literal defining the route path
2573///
2574/// # Dependencies
2575///
2576/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
2577#[proc_macro_attribute]
2578pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
2579 route_macro(attr, item)
2580}
2581
2582/// Registers a function as a request middleware.
2583///
2584/// This attribute macro registers the decorated function to be executed as a middleware
2585/// for incoming requests. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
2586///
2587/// # Note
2588///
2589/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
2590///
2591/// # Usage
2592///
2593/// ```rust
2594/// use hyperlane::*;
2595/// use hyperlane_macros::*;
2596///
2597/// #[request_middleware]
2598/// struct RequestMiddleware;
2599///
2600/// impl ServerHook for RequestMiddleware {
2601/// async fn new(_ctx: &Context) -> Self {
2602/// Self
2603/// }
2604///
2605/// #[epilogue_macros(
2606/// response_status_code(200),
2607/// response_version(HttpVersion::HTTP1_1),
2608/// response_header(SERVER => HYPERLANE)
2609/// )]
2610/// async fn handle(self, ctx: &Context) {}
2611/// }
2612/// ```
2613///
2614/// # Dependencies
2615///
2616/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
2617#[proc_macro_attribute]
2618pub fn request_middleware(attr: TokenStream, item: TokenStream) -> TokenStream {
2619 request_middleware_macro(attr, item)
2620}
2621
2622/// Registers a function as a response middleware.
2623///
2624/// This attribute macro registers the decorated function to be executed as a middleware
2625/// for outgoing responses. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
2626///
2627/// # Note
2628///
2629/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
2630///
2631/// # Usage
2632///
2633/// ```rust
2634/// use hyperlane::*;
2635/// use hyperlane_macros::*;
2636///
2637/// #[response_middleware]
2638/// struct ResponseMiddleware1;
2639///
2640/// impl ServerHook for ResponseMiddleware1 {
2641/// async fn new(_ctx: &Context) -> Self {
2642/// Self
2643/// }
2644///
2645/// async fn handle(self, ctx: &Context) {}
2646/// }
2647/// ```
2648///
2649/// # Dependencies
2650///
2651/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
2652#[proc_macro_attribute]
2653pub fn response_middleware(attr: TokenStream, item: TokenStream) -> TokenStream {
2654 response_middleware_macro(attr, item)
2655}
2656
2657/// Registers a function as a panic hook.
2658///
2659/// This attribute macro registers the decorated function to handle panics that occur
2660/// during request processing. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
2661///
2662/// # Note
2663///
2664/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
2665///
2666/// # Usage
2667///
2668/// ```rust
2669/// use hyperlane::*;
2670/// use hyperlane_macros::*;
2671///
2672/// #[panic_hook]
2673/// #[panic_hook(1)]
2674/// #[panic_hook("2")]
2675/// struct PanicHook;
2676///
2677/// impl ServerHook for PanicHook {
2678/// async fn new(_ctx: &Context) -> Self {
2679/// Self
2680/// }
2681///
2682/// #[epilogue_macros(response_body("panic_hook"), send)]
2683/// async fn handle(self, ctx: &Context) {}
2684/// }
2685/// ```
2686///
2687/// # Dependencies
2688///
2689/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
2690#[proc_macro_attribute]
2691pub fn panic_hook(attr: TokenStream, item: TokenStream) -> TokenStream {
2692 panic_hook_macro(attr, item)
2693}
2694
2695/// Injects a list of macros before the decorated function.
2696///
2697/// The macros are applied in head-insertion order, meaning the first macro in the list
2698/// is the outermost macro.
2699///
2700/// # Usage
2701///
2702/// ```rust
2703/// use hyperlane::*;
2704/// use hyperlane_macros::*;
2705///
2706/// #[route("/post")]
2707/// struct Post;
2708///
2709/// impl ServerHook for Post {
2710/// async fn new(_ctx: &Context) -> Self {
2711/// Self
2712/// }
2713///
2714/// #[prologue_macros(post, response_body("post"), send_once)]
2715/// async fn handle(self, ctx: &Context) {}
2716/// }
2717/// ```
2718#[proc_macro_attribute]
2719pub fn prologue_macros(attr: TokenStream, item: TokenStream) -> TokenStream {
2720 prologue_macros_macro(attr, item)
2721}
2722
2723/// Injects a list of macros after the decorated function.
2724///
2725/// The macros are applied in tail-insertion order, meaning the last macro in the list
2726/// is the outermost macro.
2727///
2728/// # Usage
2729///
2730/// ```rust
2731/// use hyperlane::*;
2732/// use hyperlane_macros::*;
2733///
2734/// #[response_middleware(2)]
2735/// struct ResponseMiddleware2;
2736///
2737/// impl ServerHook for ResponseMiddleware2 {
2738/// async fn new(_ctx: &Context) -> Self {
2739/// Self
2740/// }
2741///
2742/// #[epilogue_macros(send, flush)]
2743/// async fn handle(self, ctx: &Context) {}
2744/// }
2745/// ```
2746#[proc_macro_attribute]
2747pub fn epilogue_macros(attr: TokenStream, item: TokenStream) -> TokenStream {
2748 epilogue_macros_macro(attr, item)
2749}
2750
2751/// Sends only the response body with data after function execution.
2752///
2753/// This attribute macro ensures that only the response body is automatically sent
2754/// to the client after the function completes, handling request headers separately,
2755/// with the specified data.
2756///
2757/// # Usage
2758///
2759/// ```rust
2760/// use hyperlane::*;
2761/// use hyperlane_macros::*;
2762///
2763/// #[route("/send_body_with_data")]
2764/// struct SendBodyWithData;
2765///
2766/// impl ServerHook for SendBodyWithData {
2767/// async fn new(_ctx: &Context) -> Self {
2768/// Self
2769/// }
2770///
2771/// #[epilogue_macros(send_body_with_data("Response body content"))]
2772/// async fn handle(self, ctx: &Context) {}
2773/// }
2774/// ```
2775///
2776/// The macro accepts data to send and should be applied to async functions
2777/// that accept a `&Context` parameter.
2778#[proc_macro_attribute]
2779pub fn send_body_with_data(attr: TokenStream, item: TokenStream) -> TokenStream {
2780 send_body_with_data_macro(attr, item, Position::Epilogue)
2781}
2782
2783/// Wraps function body with WebSocket stream processing.
2784///
2785/// This attribute macro generates code that wraps the function body with a check to see if
2786/// data can be read from a WebSocket stream. The function body is only executed
2787/// if data is successfully read from the stream.
2788///
2789/// This attribute macro generates code that wraps the function body with a check to see if
2790/// data can be read from a WebSocket stream. The function body is only executed
2791/// if data is successfully read from the stream.
2792///
2793/// # Arguments
2794///
2795/// - `TokenStream`: The buffer to read from the WebSocket stream.
2796/// - `TokenStream`: The function item to be modified
2797///
2798/// # Returns
2799///
2800/// Returns a TokenStream containing the modified function with WebSocket stream processing logic.
2801///
2802/// # Examples
2803///
2804/// Using no parameters (default buffer size):
2805/// ```rust
2806/// use hyperlane::*;
2807/// use hyperlane_macros::*;
2808///
2809/// #[route("/ws1")]
2810/// struct Websocket1;
2811///
2812/// impl ServerHook for Websocket1 {
2813/// async fn new(_ctx: &Context) -> Self {
2814/// Self
2815/// }
2816///
2817/// #[ws]
2818/// #[ws_from_stream]
2819/// async fn handle(self, ctx: &Context) {
2820/// let body: RequestBody = ctx.get_request_body().await;
2821/// let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
2822/// ctx.send_body_list_with_data(&body_list).await.unwrap();
2823/// }
2824/// }
2825/// ```
2826///
2827/// Using only buffer size:
2828/// ```rust
2829/// use hyperlane::*;
2830/// use hyperlane_macros::*;
2831///
2832/// #[route("/ws5")]
2833/// struct Websocket5;
2834///
2835/// impl ServerHook for Websocket5 {
2836/// async fn new(_ctx: &Context) -> Self {
2837/// Self
2838/// }
2839///
2840/// #[ws]
2841/// #[ws_from_stream(1024)]
2842/// async fn handle(self, ctx: &Context) {
2843/// let body: RequestBody = ctx.get_request_body().await;
2844/// let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
2845/// ctx.send_body_list_with_data(&body_list).await.unwrap();
2846/// }
2847/// }
2848/// ```
2849///
2850/// Using variable name to store request data:
2851/// ```rust
2852/// use hyperlane::*;
2853/// use hyperlane_macros::*;
2854///
2855/// #[route("/ws2")]
2856/// struct Websocket2;
2857///
2858/// impl ServerHook for Websocket2 {
2859/// async fn new(_ctx: &Context) -> Self {
2860/// Self
2861/// }
2862///
2863/// #[ws]
2864/// #[ws_from_stream(request)]
2865/// async fn handle(self, ctx: &Context) {
2866/// let body: &RequestBody = &request.get_body();
2867/// let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(body);
2868/// ctx.send_body_list_with_data(&body_list).await.unwrap();
2869/// }
2870/// }
2871/// ```
2872///
2873/// Using buffer size and variable name:
2874/// ```rust
2875/// use hyperlane::*;
2876/// use hyperlane_macros::*;
2877///
2878/// #[route("/ws3")]
2879/// struct Websocket3;
2880///
2881/// impl ServerHook for Websocket3 {
2882/// async fn new(_ctx: &Context) -> Self {
2883/// Self
2884/// }
2885///
2886/// #[ws]
2887/// #[ws_from_stream(1024, request)]
2888/// async fn handle(self, ctx: &Context) {
2889/// let body: &RequestBody = request.get_body();
2890/// let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
2891/// ctx.send_body_list_with_data(&body_list).await.unwrap();
2892/// }
2893/// }
2894/// ```
2895///
2896/// Using variable name and buffer size (reversed order):
2897/// ```rust
2898/// use hyperlane::*;
2899/// use hyperlane_macros::*;
2900///
2901/// #[route("/ws4")]
2902/// struct Websocket4;
2903///
2904/// impl ServerHook for Websocket4 {
2905/// async fn new(_ctx: &Context) -> Self {
2906/// Self
2907/// }
2908///
2909/// #[ws]
2910/// #[ws_from_stream(request, 1024)]
2911/// async fn handle(self, ctx: &Context) {
2912/// let body: &RequestBody = request.get_body();
2913/// let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
2914/// ctx.send_body_list_with_data(&body_list).await.unwrap();
2915/// }
2916/// }
2917///
2918/// impl Websocket4 {
2919/// #[ws_from_stream(request)]
2920/// async fn ws_from_stream_with_ref_self(&self, ctx: &Context) {}
2921/// }
2922///
2923/// #[ws_from_stream]
2924/// async fn standalone_ws_from_stream_handler(ctx: &Context) {}
2925/// ```
2926#[proc_macro_attribute]
2927pub fn ws_from_stream(attr: TokenStream, item: TokenStream) -> TokenStream {
2928 ws_from_stream_macro(attr, item)
2929}
2930
2931/// Wraps function body with HTTP stream processing.
2932///
2933/// This attribute macro generates code that wraps the function body with a check to see if
2934/// data can be read from an HTTP stream. The function body is only executed
2935/// if data is successfully read from the stream.
2936///
2937/// This attribute macro generates code that wraps the function body with a check to see if
2938/// data can be read from an HTTP stream. The function body is only executed
2939/// if data is successfully read from the stream.
2940///
2941/// # Arguments
2942///
2943/// - `TokenStream`: The buffer to read from the HTTP stream.
2944/// - `TokenStream`: The function item to be modified
2945///
2946/// # Returns
2947///
2948/// Returns a TokenStream containing the modified function with HTTP stream processing logic.
2949///
2950/// # Examples
2951///
2952/// Using with epilogue_macros:
2953/// ```rust
2954/// use hyperlane::*;
2955/// use hyperlane_macros::*;
2956///
2957/// #[route("/request_query")]
2958/// struct RequestQuery;
2959///
2960/// impl ServerHook for RequestQuery {
2961/// async fn new(_ctx: &Context) -> Self {
2962/// Self
2963/// }
2964///
2965/// #[epilogue_macros(
2966/// request_query("test" => request_query_option),
2967/// response_body(&format!("request query: {request_query_option:?}")),
2968/// send,
2969/// http_from_stream(1024)
2970/// )]
2971/// async fn handle(self, ctx: &Context) {}
2972/// }
2973/// ```
2974///
2975/// Using with variable name:
2976/// ```rust
2977/// use hyperlane::*;
2978/// use hyperlane_macros::*;
2979///
2980/// #[route("/http_from_stream")]
2981/// struct HttpFromStreamTest;
2982///
2983/// impl ServerHook for HttpFromStreamTest {
2984/// async fn new(_ctx: &Context) -> Self {
2985/// Self
2986/// }
2987///
2988/// #[epilogue_macros(
2989/// http_from_stream(_request)
2990/// )]
2991/// async fn handle(self, ctx: &Context) {}
2992/// }
2993///
2994/// impl HttpFromStreamTest {
2995/// #[http_from_stream(_request)]
2996/// async fn http_from_stream_with_ref_self(&self, ctx: &Context) {}
2997/// }
2998///
2999/// #[http_from_stream]
3000/// async fn standalone_http_from_stream_handler(ctx: &Context) {}
3001/// ```
3002#[proc_macro_attribute]
3003pub fn http_from_stream(attr: TokenStream, item: TokenStream) -> TokenStream {
3004 http_from_stream_macro(attr, item)
3005}