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