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