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