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