hyperlane_macros/lib.rs
1//! hyperlane-macros
2//!
3//! A comprehensive collection of procedural macros for building
4//! HTTP servers with enhanced functionality. This crate provides
5//! attribute macros that simplify HTTP request handling, protocol
6//! validation, response management, and request data extraction.
7
8mod aborted;
9mod closed;
10mod common;
11mod filter;
12mod flush;
13mod from_stream;
14mod hook;
15mod host;
16mod http;
17mod hyperlane;
18mod inject;
19mod protocol;
20mod referer;
21mod reject;
22mod request;
23mod request_middleware;
24mod response;
25mod response_middleware;
26mod route;
27mod send;
28mod stream;
29
30pub(crate) use aborted::*;
31pub(crate) use closed::*;
32pub(crate) use common::*;
33pub(crate) use filter::*;
34pub(crate) use flush::*;
35pub(crate) use from_stream::*;
36pub(crate) use hook::*;
37pub(crate) use host::*;
38pub(crate) use http::*;
39pub(crate) use hyperlane::*;
40pub(crate) use inject::*;
41pub(crate) use protocol::*;
42pub(crate) use referer::*;
43pub(crate) use reject::*;
44pub(crate) use request::*;
45pub(crate) use request_middleware::*;
46pub(crate) use response::*;
47pub(crate) use response_middleware::*;
48pub(crate) use route::*;
49pub(crate) use send::*;
50pub(crate) use stream::*;
51
52pub(crate) use proc_macro::TokenStream;
53pub(crate) use proc_macro2::TokenStream as TokenStream2;
54pub(crate) use quote::quote;
55pub(crate) use syn::{
56 Ident, Token,
57 parse::{Parse, ParseStream, Parser, Result},
58 punctuated::Punctuated,
59 token::Comma,
60 *,
61};
62
63inventory::collect!(InjectableMacro);
64
65/// Restricts function execution to HTTP GET requests only.
66///
67/// This attribute macro ensures the decorated function only executes when the incoming request
68/// uses the GET HTTP method. Requests with other methods will be filtered out.
69///
70/// # Usage
71///
72/// ```rust
73/// use hyperlane::*;
74/// use hyperlane_macros::*;
75///
76/// #[get]
77/// async fn handle_get(ctx: Context) {
78/// // Function body
79/// }
80/// ```
81///
82/// The macro takes no parameters and should be applied directly to async functions
83/// that accept a `Context` parameter.
84#[proc_macro_attribute]
85pub fn get(_attr: TokenStream, item: TokenStream) -> TokenStream {
86 get_handler(item, Position::Prologue)
87}
88
89/// Restricts function execution to HTTP POST requests only.
90///
91/// This attribute macro ensures the decorated function only executes when the incoming request
92/// uses the POST HTTP method. Requests with other methods will be filtered out.
93///
94/// # Usage
95///
96/// ```rust
97/// use hyperlane::*;
98/// use hyperlane_macros::*;
99///
100/// #[post]
101/// async fn handle_post(ctx: Context) {
102/// // Function body
103/// }
104/// ```
105///
106/// The macro takes no parameters and should be applied directly to async functions
107/// that accept a `Context` parameter.
108#[proc_macro_attribute]
109pub fn post(_attr: TokenStream, item: TokenStream) -> TokenStream {
110 epilogue_handler(item, Position::Prologue)
111}
112
113/// Restricts function execution to HTTP PUT requests only.
114///
115/// This attribute macro ensures the decorated function only executes when the incoming request
116/// uses the PUT HTTP method. Requests with other methods will be filtered out.
117///
118/// # Usage
119///
120/// ```rust
121/// use hyperlane::*;
122/// use hyperlane_macros::*;
123///
124/// #[put]
125/// async fn handle_put(ctx: Context) {
126/// // Function body
127/// }
128/// ```
129///
130/// The macro takes no parameters and should be applied directly to async functions
131/// that accept a `Context` parameter.
132#[proc_macro_attribute]
133pub fn put(_attr: TokenStream, item: TokenStream) -> TokenStream {
134 put_handler(item, Position::Prologue)
135}
136
137/// Restricts function execution to HTTP DELETE requests only.
138///
139/// This attribute macro ensures the decorated function only executes when the incoming request
140/// uses the DELETE HTTP method. Requests with other methods will be filtered out.
141///
142/// # Usage
143///
144/// ```rust
145/// use hyperlane::*;
146/// use hyperlane_macros::*;
147///
148/// #[delete]
149/// async fn handle_delete(ctx: Context) {
150/// // Function body
151/// }
152/// ```
153///
154/// The macro takes no parameters and should be applied directly to async functions
155/// that accept a `Context` parameter.
156#[proc_macro_attribute]
157pub fn delete(_attr: TokenStream, item: TokenStream) -> TokenStream {
158 delete_handler(item, Position::Prologue)
159}
160
161/// Restricts function execution to HTTP PATCH requests only.
162///
163/// This attribute macro ensures the decorated function only executes when the incoming request
164/// uses the PATCH HTTP method. Requests with other methods will be filtered out.
165///
166/// # Usage
167///
168/// ```rust
169/// use hyperlane::*;
170/// use hyperlane_macros::*;
171///
172/// #[patch]
173/// async fn handle_patch(ctx: Context) {
174/// // Function body
175/// }
176/// ```
177///
178/// The macro takes no parameters and should be applied directly to async functions
179/// that accept a `Context` parameter.
180#[proc_macro_attribute]
181pub fn patch(_attr: TokenStream, item: TokenStream) -> TokenStream {
182 patch_handler(item, Position::Prologue)
183}
184
185/// Restricts function execution to HTTP HEAD requests only.
186///
187/// This attribute macro ensures the decorated function only executes when the incoming request
188/// uses the HEAD HTTP method. Requests with other methods will be filtered out.
189///
190/// # Usage
191///
192/// ```rust
193/// use hyperlane::*;
194/// use hyperlane_macros::*;
195///
196/// #[head]
197/// async fn handle_head(ctx: Context) {
198/// // Function body
199/// }
200/// ```
201///
202/// The macro takes no parameters and should be applied directly to async functions
203/// that accept a `Context` parameter.
204#[proc_macro_attribute]
205pub fn head(_attr: TokenStream, item: TokenStream) -> TokenStream {
206 head_handler(item, Position::Prologue)
207}
208
209/// Restricts function execution to HTTP OPTIONS requests only.
210///
211/// This attribute macro ensures the decorated function only executes when the incoming request
212/// uses the OPTIONS HTTP method. Requests with other methods will be filtered out.
213///
214/// # Usage
215///
216/// ```rust
217/// use hyperlane::*;
218/// use hyperlane_macros::*;
219///
220/// #[options]
221/// async fn handle_options(ctx: Context) {
222/// // Function body
223/// }
224/// ```
225///
226/// The macro takes no parameters and should be applied directly to async functions
227/// that accept a `Context` parameter.
228#[proc_macro_attribute]
229pub fn options(_attr: TokenStream, item: TokenStream) -> TokenStream {
230 options_handler(item, Position::Prologue)
231}
232
233/// Restricts function execution to HTTP CONNECT requests only.
234///
235/// This attribute macro ensures the decorated function only executes when the incoming request
236/// uses the CONNECT HTTP method. Requests with other methods will be filtered out.
237///
238/// # Usage
239///
240/// ```rust
241/// use hyperlane::*;
242/// use hyperlane_macros::*;
243///
244/// #[connect]
245/// async fn handle_connect(ctx: Context) {
246/// // Function body
247/// }
248/// ```
249///
250/// The macro takes no parameters and should be applied directly to async functions
251/// that accept a `Context` parameter.
252#[proc_macro_attribute]
253pub fn connect(_attr: TokenStream, item: TokenStream) -> TokenStream {
254 connect_handler(item, Position::Prologue)
255}
256
257/// Restricts function execution to HTTP TRACE requests only.
258///
259/// This attribute macro ensures the decorated function only executes when the incoming request
260/// uses the TRACE HTTP method. Requests with other methods will be filtered out.
261///
262/// # Usage
263///
264/// ```rust
265/// use hyperlane::*;
266/// use hyperlane_macros::*;
267///
268/// #[trace]
269/// async fn handle_trace(ctx: Context) {
270/// // Function body
271/// }
272/// ```
273///
274/// The macro takes no parameters and should be applied directly to async functions
275/// that accept a `Context` parameter.
276#[proc_macro_attribute]
277pub fn trace(_attr: TokenStream, item: TokenStream) -> TokenStream {
278 trace_handler(item, Position::Prologue)
279}
280
281/// Allows function to handle multiple HTTP methods.
282///
283/// This attribute macro configures the decorated function to execute for any of the specified
284/// HTTP methods. Methods should be provided as a comma-separated list.
285///
286/// # Usage
287///
288/// ```rust
289/// use hyperlane::*;
290/// use hyperlane_macros::*;
291///
292/// #[methods(get, post)]
293/// async fn handle_get_post(ctx: Context) {
294/// // Function body
295/// }
296///
297/// #[methods(put, patch, delete)]
298/// async fn handle_modifications(ctx: Context) {
299/// // Function body
300/// }
301/// ```
302///
303/// The macro accepts a comma-separated list of HTTP method names (lowercase) and should be
304/// applied to async functions that accept a `Context` parameter.
305#[proc_macro_attribute]
306pub fn methods(attr: TokenStream, item: TokenStream) -> TokenStream {
307 methods_macro(attr, item, Position::Prologue)
308}
309
310/// Restricts function execution to WebSocket upgrade requests only.
311///
312/// This attribute macro ensures the decorated function only executes when the incoming request
313/// is a valid WebSocket upgrade request with proper request headers and protocol negotiation.
314///
315/// # Usage
316///
317/// ```rust
318/// use hyperlane::*;
319/// use hyperlane_macros::*;
320///
321/// #[ws]
322/// async fn handle_websocket(ctx: Context) {
323/// // WebSocket handling logic
324/// }
325/// ```
326///
327/// The macro takes no parameters and should be applied directly to async functions
328/// that accept a `Context` parameter.
329#[proc_macro_attribute]
330pub fn ws(_attr: TokenStream, item: TokenStream) -> TokenStream {
331 ws_macro(item, Position::Prologue)
332}
333
334/// Restricts function execution to standard HTTP requests only.
335///
336/// This attribute macro ensures the decorated function only executes for standard HTTP requests,
337/// excluding WebSocket upgrades and other protocol upgrade requests.
338///
339/// # Usage
340///
341/// ```rust
342/// use hyperlane::*;
343/// use hyperlane_macros::*;
344///
345/// #[http]
346/// async fn handle_http(ctx: Context) {
347/// // HTTP request handling logic
348/// }
349/// ```
350///
351/// The macro takes no parameters and should be applied directly to async functions
352/// that accept a `Context` parameter.
353#[proc_macro_attribute]
354pub fn http(_attr: TokenStream, item: TokenStream) -> TokenStream {
355 http_macro(item, Position::Prologue)
356}
357
358/// Sets the HTTP status code for the response.
359///
360/// This attribute macro configures the HTTP status code that will be sent with the response.
361/// The status code can be provided as a numeric literal or a global constant.
362///
363/// # Usage
364///
365/// ```rust
366/// use hyperlane::*;
367/// use hyperlane_macros::*;
368///
369/// const CUSTOM_STATUS: i32 = 418;
370///
371/// #[response_status_code(200)]
372/// async fn success_handler(ctx: Context) {
373/// // Response will have status code 200
374/// }
375///
376/// #[response_status_code(404)]
377/// async fn not_found_handler(ctx: Context) {
378/// // Response will have status code 404
379/// }
380///
381/// #[response_status_code(CUSTOM_STATUS)]
382/// async fn custom_handler(ctx: Context) {
383/// // Response will have status code from global constant
384/// }
385/// ```
386///
387/// The macro accepts a numeric HTTP status code or a global constant
388/// and should be applied to async functions that accept a `Context` parameter.
389#[proc_macro_attribute]
390pub fn response_status_code(attr: TokenStream, item: TokenStream) -> TokenStream {
391 response_status_code_macro(attr, item, Position::Prologue)
392}
393
394/// Sets the HTTP reason phrase for the response.
395///
396/// This attribute macro configures the HTTP reason phrase that accompanies the status code.
397/// The reason phrase can be provided as a string literal or a global constant.
398///
399/// # Usage
400///
401/// ```rust
402/// use hyperlane::*;
403/// use hyperlane_macros::*;
404///
405/// const CUSTOM_REASON: &str = "I'm a teapot";
406///
407/// #[response_reason_phrase("OK")]
408/// async fn success_handler(ctx: Context) {
409/// // Response will have reason phrase "OK"
410/// }
411///
412/// #[response_reason_phrase("Not Found")]
413/// async fn not_found_handler(ctx: Context) {
414/// // Response will have reason phrase "Not Found"
415/// }
416///
417/// #[response_reason_phrase(CUSTOM_REASON)]
418/// async fn custom_handler(ctx: Context) {
419/// // Response will have reason phrase from global constant
420/// }
421/// ```
422///
423/// The macro accepts a string literal or global constant for the reason phrase and should be
424/// applied to async functions that accept a `Context` parameter.
425#[proc_macro_attribute]
426pub fn response_reason_phrase(attr: TokenStream, item: TokenStream) -> TokenStream {
427 response_reason_phrase_macro(attr, item, Position::Prologue)
428}
429
430/// Sets or replaces a specific HTTP response header.
431///
432/// This attribute macro configures a specific HTTP response header that will be sent with the response.
433/// Both the header name and value can be provided as string literals or global constants.
434/// Use `"key", "value"` to set a header (add to existing headers) or `"key" => "value"` to replace a header (overwrite existing).
435///
436/// # Usage
437///
438/// ```rust
439/// use hyperlane::*;
440/// use hyperlane_macros::*;
441///
442/// const HEADER_NAME: &str = "X-Custom-Header";
443/// const HEADER_VALUE: &str = "custom-value";
444///
445/// #[response_header("Content-Type", "application/json")]
446/// async fn json_handler(ctx: Context) {
447/// // Response will have Content-Type header set to application/json
448/// }
449///
450/// #[response_header("X-Static-Header" => "static-value")]
451/// async fn set_header_handler(ctx: Context) {
452/// // Response will have static header replaced (overwrite existing)
453/// }
454///
455/// #[response_header(HEADER_NAME, HEADER_VALUE)]
456/// async fn dynamic_header_handler(ctx: Context) {
457/// // Response will have header from global constants
458/// }
459///
460/// #[response_header("Cache-Control" => "no-cache")]
461/// async fn set_cache_handler(ctx: Context) {
462/// // Response will have Cache-Control header replaced
463/// }
464///
465/// #[response_header("X-Add-Header", "add-value")]
466/// #[response_header("X-Set-Header" => "set-value")]
467/// async fn header_operations_handler(ctx: Context) {
468/// // Response will have X-Add-Header set and X-Set-Header replaced
469/// }
470/// ```
471///
472/// The macro accepts header name and header value, both can be string literals or global constants.
473/// Use `"key", "value"` for setting headers and `"key" => "value"` for replacing headers.
474/// Should be applied to async functions that accept a `Context` parameter.
475#[proc_macro_attribute]
476pub fn response_header(attr: TokenStream, item: TokenStream) -> TokenStream {
477 response_header_macro(attr, item, Position::Prologue)
478}
479
480/// Sets the HTTP response body.
481///
482/// This attribute macro configures the HTTP response body that will be sent with the response.
483/// The body content can be provided as a string literal or a global constant.
484///
485/// # Usage
486///
487/// ```rust
488/// use hyperlane::*;
489/// use hyperlane_macros::*;
490///
491/// const RESPONSE_DATA: &str = "Dynamic content from constant";
492///
493/// #[response_body("Hello, World!")]
494/// async fn hello_handler(ctx: Context) {
495/// // Response will have body "Hello, World!"
496/// }
497///
498/// #[response_body("{\"message\": \"success\"}")]
499/// async fn json_response_handler(ctx: Context) {
500/// // Response will have JSON body
501/// }
502///
503/// #[response_body(RESPONSE_DATA)]
504/// async fn dynamic_body_handler(ctx: Context) {
505/// // Response will have body from global constant
506/// }
507/// ```
508///
509/// The macro accepts a string literal or global constant for the response body and should be
510/// applied to async functions that accept a `Context` parameter.
511#[proc_macro_attribute]
512pub fn response_body(attr: TokenStream, item: TokenStream) -> TokenStream {
513 response_body_macro(attr, item, Position::Prologue)
514}
515
516/// Clears all response headers.
517///
518/// This attribute macro clears all response headers from the response.
519///
520/// # Usage
521///
522/// ```rust
523/// use hyperlane::*;
524/// use hyperlane_macros::*;
525///
526/// #[clear_response_headers]
527/// async fn clear_headers(ctx: Context) {
528/// // Clear all response headers
529/// }
530/// ```
531///
532/// The macro should be applied to async functions that accept a `Context` parameter.
533#[proc_macro_attribute]
534pub fn clear_response_headers(_attr: TokenStream, item: TokenStream) -> TokenStream {
535 clear_response_headers_macro(item, Position::Prologue)
536}
537
538/// Sets the HTTP response version.
539///
540/// This attribute macro configures the HTTP response version that will be sent with the response.
541/// The version can be provided as a variable or code block.
542///
543/// # Usage
544///
545/// ```rust
546/// use hyperlane::*;
547/// use hyperlane_macros::*;
548///
549/// #[response_version(HttpVersion::HTTP1_1)]
550/// async fn version_from_constant(ctx: Context) {
551/// // Response will have version from global constant
552/// }
553/// ```
554///
555/// The macro accepts a variable or code block for the response version and should be
556/// applied to async functions that accept a `Context` parameter.
557#[proc_macro_attribute]
558pub fn response_version(attr: TokenStream, item: TokenStream) -> TokenStream {
559 response_version_macro(attr, item, Position::Prologue)
560}
561
562/// Automatically sends the complete response after function execution.
563///
564/// This attribute macro ensures that the response (request headers and body) is automatically sent
565/// to the client after the function completes execution.
566///
567/// # Usage
568///
569/// ```rust
570/// use hyperlane::*;
571/// use hyperlane_macros::*;
572///
573/// #[send]
574/// async fn auto_send_handler(ctx: Context) {
575/// let _ = ctx.set_response_body("Hello World").await;
576/// // Response is automatically sent after function returns
577/// }
578/// ```
579///
580/// The macro takes no parameters and should be applied directly to async functions
581/// that accept a `Context` parameter.
582#[proc_macro_attribute]
583pub fn send(_attr: TokenStream, item: TokenStream) -> TokenStream {
584 send_macro(item, Position::Epilogue)
585}
586
587/// Automatically sends only the response body after function execution.
588///
589/// This attribute macro ensures that only the response body is automatically sent
590/// to the client after the function completes, handling request headers separately.
591///
592/// # Usage
593///
594/// ```rust
595/// use hyperlane::*;
596/// use hyperlane_macros::*;
597///
598/// #[send_body]
599/// async fn auto_send_body_handler(ctx: Context) {
600/// let _ = ctx.set_response_body("Response body content").await;
601/// // Only response body is automatically sent after function returns
602/// }
603/// ```
604///
605/// The macro takes no parameters and should be applied directly to async functions
606/// that accept a `Context` parameter.
607#[proc_macro_attribute]
608pub fn send_body(_attr: TokenStream, item: TokenStream) -> TokenStream {
609 send_body_macro(item, Position::Epilogue)
610}
611
612/// Sends the complete response with data after function execution.
613///
614/// This attribute macro ensures that the response (request headers and body) is automatically sent
615/// to the client after the function completes execution, with the specified data.
616///
617/// # Usage
618///
619/// ```rust
620/// use hyperlane::*;
621/// use hyperlane_macros::*;
622///
623/// #[send_with_data("Hello, World!")]
624/// async fn auto_send_with_data_handler(ctx: Context) {
625/// // Response is automatically sent with the specified data after function returns
626/// }
627/// ```
628///
629/// The macro accepts data to send and should be applied to async functions
630/// that accept a `Context` parameter.
631#[proc_macro_attribute]
632pub fn send_with_data(attr: TokenStream, item: TokenStream) -> TokenStream {
633 send_with_data_macro(attr, item, Position::Epilogue)
634}
635
636/// Sends the complete response exactly once after function execution.
637///
638/// This attribute macro ensures that the response is sent exactly once to the client,
639/// preventing multiple response transmissions for single-use scenarios.
640///
641/// # Usage
642///
643/// ```rust
644/// use hyperlane::*;
645/// use hyperlane_macros::*;
646///
647/// #[send_once]
648/// async fn send_once_handler(ctx: Context) {
649/// let _ = ctx.set_response_body("One-time response").await;
650/// // Response is sent exactly once after function returns
651/// }
652/// ```
653///
654/// The macro takes no parameters and should be applied directly to async functions
655/// that accept a `Context` parameter.
656#[proc_macro_attribute]
657pub fn send_once(_attr: TokenStream, item: TokenStream) -> TokenStream {
658 send_once_macro(item, Position::Epilogue)
659}
660
661/// Sends only the response body exactly once after function execution.
662///
663/// This attribute macro ensures that the response body is sent exactly once to the client,
664/// preventing multiple body transmissions for single-use scenarios.
665///
666/// # Usage
667///
668/// ```rust
669/// use hyperlane::*;
670/// use hyperlane_macros::*;
671///
672/// #[send_body_once]
673/// async fn send_body_once_handler(ctx: Context) {
674/// let _ = ctx.set_response_body("One-time body content").await;
675/// // Response body is sent exactly once after function returns
676/// }
677/// ```
678///
679/// The macro takes no parameters and should be applied directly to async functions
680/// that accept a `Context` parameter.
681#[proc_macro_attribute]
682pub fn send_body_once(_attr: TokenStream, item: TokenStream) -> TokenStream {
683 send_body_once_macro(item, Position::Epilogue)
684}
685
686/// Sends the complete response exactly once with data after function execution.
687///
688/// This attribute macro ensures that the response is sent exactly once to the client,
689/// preventing multiple response transmissions for single-use scenarios, with the specified data.
690///
691/// # Usage
692///
693/// ```rust
694/// use hyperlane::*;
695/// use hyperlane_macros::*;
696///
697/// #[send_once_with_data("One-time response")]
698/// async fn send_once_with_data_handler(ctx: Context) {
699/// // Response is sent exactly once with the specified data after function returns
700/// }
701/// ```
702///
703/// The macro accepts data to send and should be applied to async functions
704/// that accept a `Context` parameter.
705#[proc_macro_attribute]
706pub fn send_once_with_data(attr: TokenStream, item: TokenStream) -> TokenStream {
707 send_once_with_data_macro(attr, item, Position::Epilogue)
708}
709
710/// Flushes the response stream after function execution.
711///
712/// This attribute macro ensures that the response stream is flushed to guarantee immediate
713/// data transmission, forcing any buffered response data to be sent to the client.
714///
715/// # Usage
716///
717/// ```rust
718/// use hyperlane::*;
719/// use hyperlane_macros::*;
720///
721/// #[flush]
722/// async fn flush_handler(ctx: Context) {
723/// let _ = ctx.set_response_body("Immediate response").await;
724/// // Response stream is flushed after function returns
725/// }
726/// ```
727///
728/// The macro takes no parameters and should be applied directly to async functions
729/// that accept a `Context` parameter.
730#[proc_macro_attribute]
731pub fn flush(_attr: TokenStream, item: TokenStream) -> TokenStream {
732 flush_macro(item, Position::Prologue)
733}
734
735/// Handles aborted request scenarios.
736///
737/// This attribute macro configures the function to handle cases where the client has
738/// aborted the request, providing appropriate handling for interrupted or cancelled requests.
739///
740/// # Usage
741///
742/// ```rust
743/// use hyperlane::*;
744/// use hyperlane_macros::*;
745///
746/// #[aborted]
747/// async fn handle_aborted(ctx: Context) {
748/// // Handle aborted request logic
749/// }
750/// ```
751///
752/// The macro takes no parameters and should be applied directly to async functions
753/// that accept a `Context` parameter.
754#[proc_macro_attribute]
755pub fn aborted(_attr: TokenStream, item: TokenStream) -> TokenStream {
756 aborted_macro(item, Position::Prologue)
757}
758
759/// Handles closed connection scenarios.
760///
761/// This attribute macro configures the function to handle cases where the connection
762/// has been closed, providing appropriate handling for terminated or disconnected connections.
763///
764/// # Usage
765///
766/// ```rust
767/// use hyperlane::*;
768/// use hyperlane_macros::*;
769///
770/// #[closed]
771/// async fn handle_closed(ctx: Context) {
772/// // Handle closed connection logic
773/// }
774/// ```
775///
776/// The macro takes no parameters and should be applied directly to async functions
777/// that accept a `Context` parameter.
778#[proc_macro_attribute]
779pub fn closed(_attr: TokenStream, item: TokenStream) -> TokenStream {
780 closed_macro(item, Position::Prologue)
781}
782
783/// Restricts function execution to HTTP/2 Cleartext (h2c) requests only.
784///
785/// This attribute macro ensures the decorated function only executes for HTTP/2 cleartext
786/// requests that use the h2c upgrade mechanism.
787///
788/// # Usage
789///
790/// ```rust
791/// use hyperlane::*;
792/// use hyperlane_macros::*;
793///
794/// #[h2c]
795/// async fn handle_h2c(ctx: Context) {
796/// // Handle HTTP/2 cleartext requests
797/// }
798/// ```
799///
800/// The macro takes no parameters and should be applied directly to async functions
801/// that accept a `Context` parameter.
802#[proc_macro_attribute]
803pub fn h2c(_attr: TokenStream, item: TokenStream) -> TokenStream {
804 h2c_macro(item, Position::Prologue)
805}
806
807/// Restricts function execution to HTTP/0.9 requests only.
808///
809/// This attribute macro ensures the decorated function only executes for HTTP/0.9
810/// protocol requests, the earliest version of the HTTP protocol.
811///
812/// # Usage
813///
814/// ```rust
815/// use hyperlane::*;
816/// use hyperlane_macros::*;
817///
818/// #[http0_9]
819/// async fn handle_http09(ctx: Context) {
820/// // Handle HTTP/0.9 requests
821/// }
822/// ```
823///
824/// The macro takes no parameters and should be applied directly to async functions
825/// that accept a `Context` parameter.
826#[proc_macro_attribute]
827pub fn http0_9(_attr: TokenStream, item: TokenStream) -> TokenStream {
828 http0_9_macro(item, Position::Prologue)
829}
830
831/// Restricts function execution to HTTP/1.0 requests only.
832///
833/// This attribute macro ensures the decorated function only executes for HTTP/1.0
834/// protocol requests.
835///
836/// # Usage
837///
838/// ```rust
839/// use hyperlane::*;
840/// use hyperlane_macros::*;
841///
842/// #[http1_0]
843/// async fn handle_http10(ctx: Context) {
844/// // Handle HTTP/1.0 requests
845/// }
846/// ```
847///
848/// The macro takes no parameters and should be applied directly to async functions
849/// that accept a `Context` parameter.
850#[proc_macro_attribute]
851pub fn http1_0(_attr: TokenStream, item: TokenStream) -> TokenStream {
852 http1_0_macro(item, Position::Prologue)
853}
854
855/// Restricts function execution to HTTP/1.1 requests only.
856///
857/// This attribute macro ensures the decorated function only executes for HTTP/1.1
858/// protocol requests.
859///
860/// # Usage
861///
862/// ```rust
863/// use hyperlane::*;
864/// use hyperlane_macros::*;
865///
866/// #[http1_1]
867/// async fn handle_http11(ctx: Context) {
868/// // Handle HTTP/1.1 requests
869/// }
870/// ```
871///
872/// The macro takes no parameters and should be applied directly to async functions
873/// that accept a `Context` parameter.
874#[proc_macro_attribute]
875pub fn http1_1(_attr: TokenStream, item: TokenStream) -> TokenStream {
876 http1_1_macro(item, Position::Prologue)
877}
878
879/// Restricts function execution to HTTP/1.1 or higher protocol versions.
880///
881/// This attribute macro ensures the decorated function only executes for HTTP/1.1
882/// or newer protocol versions, including HTTP/2, HTTP/3, and future versions.
883///
884/// # Usage
885///
886/// ```rust
887/// use hyperlane::*;
888/// use hyperlane_macros::*;
889///
890/// #[http1_1_or_higher]
891/// async fn handle_modern_http(ctx: Context) {
892/// // Handle HTTP/1.1, HTTP/2, HTTP/3, etc.
893/// }
894/// ```
895///
896/// The macro takes no parameters and should be applied directly to async functions
897/// that accept a `Context` parameter.
898#[proc_macro_attribute]
899pub fn http1_1_or_higher(_attr: TokenStream, item: TokenStream) -> TokenStream {
900 http1_1_or_higher_macro(item, Position::Prologue)
901}
902
903/// Restricts function execution to HTTP/2 requests only.
904///
905/// This attribute macro ensures the decorated function only executes for HTTP/2
906/// protocol requests.
907///
908/// # Usage
909///
910/// ```rust
911/// use hyperlane::*;
912/// use hyperlane_macros::*;
913///
914/// #[http2]
915/// async fn handle_http2(ctx: Context) {
916/// // Handle HTTP/2 requests
917/// }
918/// ```
919///
920/// The macro takes no parameters and should be applied directly to async functions
921/// that accept a `Context` parameter.
922#[proc_macro_attribute]
923pub fn http2(_attr: TokenStream, item: TokenStream) -> TokenStream {
924 http2_macro(item, Position::Prologue)
925}
926
927/// Restricts function execution to HTTP/3 requests only.
928///
929/// This attribute macro ensures the decorated function only executes for HTTP/3
930/// protocol requests, the latest version of the HTTP protocol.
931///
932/// # Usage
933///
934/// ```rust
935/// use hyperlane::*;
936/// use hyperlane_macros::*;
937///
938/// #[http3]
939/// async fn handle_http3(ctx: Context) {
940/// // Handle HTTP/3 requests
941/// }
942/// ```
943///
944/// The macro takes no parameters and should be applied directly to async functions
945/// that accept a `Context` parameter.
946#[proc_macro_attribute]
947pub fn http3(_attr: TokenStream, item: TokenStream) -> TokenStream {
948 http3_macro(item, Position::Prologue)
949}
950
951/// Restricts function execution to TLS-encrypted requests only.
952///
953/// This attribute macro ensures the decorated function only executes for requests
954/// that use TLS/SSL encryption on the connection.
955///
956/// # Usage
957///
958/// ```rust
959/// use hyperlane::*;
960/// use hyperlane_macros::*;
961///
962/// #[tls]
963/// async fn handle_secure(ctx: Context) {
964/// // Handle TLS-encrypted requests only
965/// }
966/// ```
967///
968/// The macro takes no parameters and should be applied directly to async functions
969/// that accept a `Context` parameter.
970#[proc_macro_attribute]
971pub fn tls(_attr: TokenStream, item: TokenStream) -> TokenStream {
972 tls_macro(item, Position::Prologue)
973}
974
975/// Filters requests based on a boolean condition.
976///
977/// The function continues execution only if the provided code block returns `true`.
978///
979/// # Usage
980///
981/// ```rust
982/// use hyperlane::*;
983/// use hyperlane_macros::*;
984///
985/// #[filter(ctx.get_request().await.is_ws())]
986/// async fn handle_ws(ctx: Context) {
987/// // This code will only run for WebSocket requests.
988/// }
989/// ```
990#[proc_macro_attribute]
991pub fn filter(attr: TokenStream, item: TokenStream) -> TokenStream {
992 filter_macro(attr, item, Position::Prologue)
993}
994
995/// Rejects requests based on a boolean condition.
996///
997/// The function continues execution only if the provided code block returns `false`.
998///
999/// # Usage
1000///
1001/// ```rust
1002/// use hyperlane::*;
1003/// use hyperlane_macros::*;
1004///
1005/// #[reject(ctx.get_request().await.is_http())]
1006/// async fn handle_non_http(ctx: Context) {
1007/// // This code will not run for HTTP requests.
1008/// }
1009/// ```
1010#[proc_macro_attribute]
1011pub fn reject(attr: TokenStream, item: TokenStream) -> TokenStream {
1012 reject_macro(attr, item, Position::Prologue)
1013}
1014
1015/// Restricts function execution to requests with a specific host.
1016///
1017/// This attribute macro ensures the decorated function only executes when the incoming request
1018/// has a host header that matches the specified value. Requests with different or missing host headers will be filtered out.
1019///
1020/// # Usage
1021///
1022/// ```rust
1023/// use hyperlane::*;
1024/// use hyperlane_macros::*;
1025///
1026/// #[host("localhost")]
1027/// async fn handle_example_com(ctx: Context) {
1028/// // Function body for localhost requests
1029/// }
1030///
1031/// #[host("api.localhost")]
1032/// async fn handle_api_subdomain(ctx: Context) {
1033/// // Function body for api.localhost requests
1034/// }
1035/// ```
1036///
1037/// The macro accepts a string literal specifying the expected host value and should be
1038/// applied to async functions that accept a `Context` parameter.
1039#[proc_macro_attribute]
1040pub fn host(attr: TokenStream, item: TokenStream) -> TokenStream {
1041 host_macro(attr, item, Position::Prologue)
1042}
1043
1044/// Reject requests that have no host header.
1045///
1046/// This attribute macro ensures the decorated function only executes when the incoming request
1047/// has a host header present. Requests without a host header will be filtered out.
1048///
1049/// # Usage
1050///
1051/// ```rust
1052/// use hyperlane::*;
1053/// use hyperlane_macros::*;
1054///
1055/// #[reject_host("localhost")]
1056/// async fn handle_with_host(ctx: Context) {
1057/// // Function body for requests with host header
1058/// }
1059/// ```
1060///
1061/// The macro takes no parameters and should be applied directly to async functions
1062/// that accept a `Context` parameter.
1063#[proc_macro_attribute]
1064pub fn reject_host(attr: TokenStream, item: TokenStream) -> TokenStream {
1065 reject_host_macro(attr, item, Position::Prologue)
1066}
1067
1068/// Restricts function execution to requests with a specific referer.
1069///
1070/// This attribute macro ensures the decorated function only executes when the incoming request
1071/// has a referer header that matches the specified value. Requests with different or missing referer headers will be filtered out.
1072///
1073/// # Usage
1074///
1075/// ```rust
1076/// use hyperlane::*;
1077/// use hyperlane_macros::*;
1078///
1079/// #[referer("http://localhost")]
1080/// async fn handle_example_referer(ctx: Context) {
1081/// // Function body for requests from localhost
1082/// }
1083///
1084/// #[referer("https://api.localhost")]
1085/// async fn handle_api_referer(ctx: Context) {
1086/// // Function body for requests from api.localhost
1087/// }
1088/// ```
1089///
1090/// The macro accepts a string literal specifying the expected referer value and should be
1091/// applied to async functions that accept a `Context` parameter.
1092#[proc_macro_attribute]
1093pub fn referer(attr: TokenStream, item: TokenStream) -> TokenStream {
1094 referer_macro(attr, item, Position::Prologue)
1095}
1096
1097/// Reject requests that have a specific referer header.
1098///
1099/// This attribute macro ensures the decorated function only executes when the incoming request
1100/// does not have a referer header that matches the specified value. Requests with the matching referer header will be filtered out.
1101///
1102/// # Usage
1103///
1104/// ```rust
1105/// use hyperlane::*;
1106/// use hyperlane_macros::*;
1107///
1108/// #[reject_referer("http://localhost")]
1109/// async fn handle_without_spam_referer(ctx: Context) {
1110/// // Function body for requests not from localhost
1111/// }
1112/// ```
1113///
1114/// The macro accepts a string literal specifying the referer value to filter out and should be
1115/// applied to async functions that accept a `Context` parameter.
1116#[proc_macro_attribute]
1117pub fn reject_referer(attr: TokenStream, item: TokenStream) -> TokenStream {
1118 reject_referer_macro(attr, item, Position::Prologue)
1119}
1120
1121/// Executes multiple specified functions before the main handler function.
1122///
1123/// This attribute macro configures multiple pre-execution hooks that run before the main function logic.
1124/// The specified hook functions will be called in the order provided, followed by the main function execution.
1125///
1126/// # Usage
1127///
1128/// ```rust
1129/// use hyperlane::*;
1130/// use hyperlane_macros::*;
1131///
1132/// #[get]
1133/// async fn prologue_handler1(ctx: Context) {
1134/// // First pre-execution logic
1135/// }
1136///
1137/// #[http]
1138/// async fn prologue_handler2(ctx: Context) {
1139/// // Second pre-execution logic
1140/// }
1141///
1142/// #[prologue_hooks(prologue_handler1, prologue_handler2)]
1143/// async fn main_handler(ctx: Context) {
1144/// // Main function logic (runs after prologue_handler1 and prologue_handler2)
1145/// }
1146/// ```
1147///
1148/// The macro accepts a comma-separated list of function names as parameters. All hook functions
1149/// and the main function must accept a `Context` parameter. Avoid combining this macro with other
1150/// macros on the same function to prevent macro expansion conflicts.
1151#[proc_macro_attribute]
1152pub fn prologue_hooks(attr: TokenStream, item: TokenStream) -> TokenStream {
1153 prologue_hooks_macro(attr, item, Position::Prologue)
1154}
1155
1156/// Executes multiple specified functions after the main handler function.
1157///
1158/// This attribute macro configures multiple post-execution hooks that run after the main function logic.
1159/// The main function will execute first, followed by the specified hook functions in the order provided.
1160///
1161/// # Usage
1162///
1163/// ```rust
1164/// use hyperlane::*;
1165/// use hyperlane_macros::*;
1166///
1167/// #[send]
1168/// async fn epilogue_handler1(ctx: Context) {
1169/// // First post-execution logic
1170/// }
1171///
1172/// #[flush]
1173/// async fn epilogue_handler2(ctx: Context) {
1174/// // Second post-execution logic
1175/// }
1176///
1177/// #[epilogue_hooks(epilogue_handler1, epilogue_handler2)]
1178/// async fn main_handler(ctx: Context) {
1179/// // Main function logic (runs before epilogue_handler1 and epilogue_handler2)
1180/// }
1181/// ```
1182///
1183/// The macro accepts a comma-separated list of function names as parameters. All hook functions
1184/// and the main function must accept a `Context` parameter. Avoid combining this macro with other
1185/// macros on the same function to prevent macro expansion conflicts.
1186#[proc_macro_attribute]
1187pub fn epilogue_hooks(attr: TokenStream, item: TokenStream) -> TokenStream {
1188 epilogue_hooks_macro(attr, item, Position::Epilogue)
1189}
1190
1191/// Extracts the raw request body into a specified variable.
1192///
1193/// This attribute macro extracts the raw request body content into a variable
1194/// with the fixed type `RequestBody`. The body content is not parsed or deserialized.
1195///
1196/// # Usage
1197///
1198/// ```rust
1199/// use hyperlane::*;
1200/// use hyperlane_macros::*;
1201///
1202/// #[request_body(raw_body)]
1203/// async fn handle_raw_body(ctx: Context) {
1204/// // Use the raw request body
1205/// let body_content = raw_body;
1206/// }
1207/// ```
1208///
1209/// The macro accepts only a variable name. The variable will be available
1210/// in the function scope as a `RequestBody` type.
1211#[proc_macro_attribute]
1212pub fn request_body(attr: TokenStream, item: TokenStream) -> TokenStream {
1213 request_body_macro(attr, item, Position::Prologue)
1214}
1215
1216/// Parses the request body as JSON into a specified variable and type.
1217///
1218/// This attribute macro extracts and deserializes the request body content as JSON into a variable
1219/// with the specified type. The body content is parsed as JSON using serde.
1220///
1221/// # Usage
1222///
1223/// ```rust
1224/// use hyperlane::*;
1225/// use hyperlane_macros::*;
1226/// use serde::Deserialize;
1227///
1228/// #[derive(Deserialize, Clone)]
1229/// struct UserData {
1230/// name: String,
1231/// age: u32,
1232/// }
1233///
1234/// #[request_body_json(user_data: UserData)]
1235/// async fn handle_user(ctx: Context) {
1236/// if let Ok(data) = user_data {
1237/// // Use the parsed user data
1238/// }
1239/// }
1240/// ```
1241///
1242/// The macro accepts a variable name and type in the format `variable_name: Type`.
1243/// The variable will be available in the function scope as a `Result<Type, JsonError>`.
1244#[proc_macro_attribute]
1245pub fn request_body_json(attr: TokenStream, item: TokenStream) -> TokenStream {
1246 request_body_json_macro(attr, item, Position::Prologue)
1247}
1248
1249/// Extracts a specific attribute value into a variable.
1250///
1251/// This attribute macro retrieves a specific attribute by key and makes it available
1252/// as a typed variable from the request context.
1253///
1254/// # Usage
1255///
1256/// ```rust
1257/// use hyperlane::*;
1258/// use hyperlane_macros::*;
1259/// use serde::Deserialize;
1260///
1261/// const USER_KEY: &str = "user_data";
1262///
1263/// #[derive(Deserialize, Clone)]
1264/// struct User {
1265/// id: u64,
1266/// name: String,
1267/// }
1268///
1269/// #[attribute(USER_KEY => user: User)]
1270/// async fn handle_with_attribute(ctx: Context) {
1271/// if let Some(user_data) = user {
1272/// // Use the extracted attribute
1273/// }
1274/// }
1275/// ```
1276///
1277/// The macro accepts a key-to-variable mapping in the format `key => variable_name: Type`.
1278/// The variable will be available as an `Option<Type>` in the function scope.
1279#[proc_macro_attribute]
1280pub fn attribute(attr: TokenStream, item: TokenStream) -> TokenStream {
1281 attribute_macro(attr, item, Position::Prologue)
1282}
1283
1284/// Extracts all attributes into a HashMap variable.
1285///
1286/// This attribute macro retrieves all available attributes from the request context
1287/// and makes them available as a HashMap for comprehensive attribute access.
1288///
1289/// # Usage
1290///
1291/// ```rust
1292/// use hyperlane::*;
1293/// use hyperlane_macros::*;
1294///
1295/// #[attributes(all_attrs)]
1296/// async fn handle_with_all_attributes(ctx: Context) {
1297/// for (key, value) in all_attrs {
1298/// // Process each attribute
1299/// }
1300/// }
1301/// ```
1302///
1303/// The macro accepts a variable name that will contain a HashMap of all attributes.
1304/// The variable will be available as a HashMap in the function scope.
1305#[proc_macro_attribute]
1306pub fn attributes(attr: TokenStream, item: TokenStream) -> TokenStream {
1307 attributes_macro(attr, item, Position::Prologue)
1308}
1309
1310/// Extracts a specific route parameter into a variable.
1311///
1312/// This attribute macro retrieves a specific route parameter by key and makes it
1313/// available as a variable. Route parameters are extracted from the URL path segments.
1314///
1315/// # Usage
1316///
1317/// ```rust
1318/// use hyperlane::*;
1319/// use hyperlane_macros::*;
1320///
1321/// // For route like "/users/{id}"
1322/// #[route_param("id" => user_id)]
1323/// async fn get_user(ctx: Context) {
1324/// if let Some(id) = user_id {
1325/// // Use the route parameter
1326/// }
1327/// }
1328/// ```
1329///
1330/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
1331/// The variable will be available as an `Option<String>` in the function scope.
1332#[proc_macro_attribute]
1333pub fn route_param(attr: TokenStream, item: TokenStream) -> TokenStream {
1334 route_param_macro(attr, item, Position::Prologue)
1335}
1336
1337/// Extracts all route parameters into a collection variable.
1338///
1339/// This attribute macro retrieves all available route parameters from the URL path
1340/// and makes them available as a collection for comprehensive route parameter access.
1341///
1342/// # Usage
1343///
1344/// ```rust
1345/// use hyperlane::*;
1346/// use hyperlane_macros::*;
1347///
1348/// // For route like "/users/{id}/posts/{epilogue_id}"
1349/// #[route_params(params)]
1350/// async fn handle_nested_route(ctx: Context) {
1351/// for (key, value) in params {
1352/// // Process each route parameter
1353/// }
1354/// }
1355/// ```
1356///
1357/// The macro accepts a variable name that will contain all route parameters.
1358/// The variable will be available as a collection in the function scope.
1359#[proc_macro_attribute]
1360pub fn route_params(attr: TokenStream, item: TokenStream) -> TokenStream {
1361 route_params_macro(attr, item, Position::Prologue)
1362}
1363
1364/// Extracts a specific request query parameter into a variable.
1365///
1366/// This attribute macro retrieves a specific request query parameter by key and makes it
1367/// available as a variable. Query parameters are extracted from the URL request query string.
1368///
1369/// # Usage
1370///
1371/// ```rust
1372/// use hyperlane::*;
1373/// use hyperlane_macros::*;
1374///
1375/// // For URL like "/search?q=rust&limit=10"
1376/// #[request_query("q" => search_term)]
1377/// async fn search(ctx: Context) {
1378/// if let Some(term) = search_term {
1379/// // Use the request query parameter
1380/// }
1381/// }
1382/// ```
1383///
1384/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
1385/// The variable will be available as an `Option<String>` in the function scope.
1386#[proc_macro_attribute]
1387pub fn request_query(attr: TokenStream, item: TokenStream) -> TokenStream {
1388 request_query_macro(attr, item, Position::Prologue)
1389}
1390
1391/// Extracts all request query parameters into a collection variable.
1392///
1393/// This attribute macro retrieves all available request query parameters from the URL request query string
1394/// and makes them available as a collection for comprehensive request query parameter access.
1395///
1396/// # Usage
1397///
1398/// ```rust
1399/// use hyperlane::*;
1400/// use hyperlane_macros::*;
1401///
1402/// // For URL like "/search?q=rust&limit=10&sort=date"
1403/// #[request_querys(all_params)]
1404/// async fn search_with_params(ctx: Context) {
1405/// for (key, value) in all_params {
1406/// // Process each request query parameter
1407/// }
1408/// }
1409/// ```
1410///
1411/// The macro accepts a variable name that will contain all request query parameters.
1412/// The variable will be available as a collection in the function scope.
1413#[proc_macro_attribute]
1414pub fn request_querys(attr: TokenStream, item: TokenStream) -> TokenStream {
1415 request_querys_macro(attr, item, Position::Prologue)
1416}
1417
1418/// Extracts a specific HTTP request header into a variable.
1419///
1420/// This attribute macro retrieves a specific HTTP request header by name and makes it
1421/// available as a variable. Header values are extracted from the request request headers collection.
1422///
1423/// # Usage
1424///
1425/// ```rust
1426/// use hyperlane::*;
1427/// use hyperlane_macros::*;
1428///
1429/// #[request_header(HOST => host_request_header)]
1430/// async fn handle_with_host(ctx: Context) {
1431/// if let Some(host) = host_request_header {
1432/// // Use the host request_header value
1433/// }
1434/// }
1435///
1436/// #[request_header("Content-Type" => content_type)]
1437/// async fn handle_with_content_type(ctx: Context) {
1438/// if let Some(ct) = content_type {
1439/// // Use the content type request_header
1440/// }
1441/// }
1442/// ```
1443///
1444/// The macro accepts a request header name-to-variable mapping in the format `HEADER_NAME => variable_name`
1445/// or `"Header-Name" => variable_name`. The variable will be available as an `Option<String>`.
1446#[proc_macro_attribute]
1447pub fn request_header(attr: TokenStream, item: TokenStream) -> TokenStream {
1448 request_header_macro(attr, item, Position::Prologue)
1449}
1450
1451/// Extracts all HTTP request headers into a collection variable.
1452///
1453/// This attribute macro retrieves all available HTTP request headers from the request
1454/// and makes them available as a collection for comprehensive request header access.
1455///
1456/// # Usage
1457///
1458/// ```rust
1459/// use hyperlane::*;
1460/// use hyperlane_macros::*;
1461///
1462/// #[request_headers(all_request_headers)]
1463/// async fn handle_with_all_request_headers(ctx: Context) {
1464/// for (name, value) in all_request_headers {
1465/// // Process each request_header
1466/// }
1467/// }
1468/// ```
1469///
1470/// The macro accepts a variable name that will contain all HTTP request headers.
1471/// The variable will be available as a collection in the function scope.
1472#[proc_macro_attribute]
1473pub fn request_headers(attr: TokenStream, item: TokenStream) -> TokenStream {
1474 request_headers_macro(attr, item, Position::Prologue)
1475}
1476
1477/// Extracts a specific cookie value or all cookies into a variable.
1478///
1479/// This attribute macro supports two syntaxes:
1480/// 1. `cookie(key => variable_name)` - Extract a specific cookie value by key
1481/// 2. `cookie(variable_name)` - Extract all cookies as a raw string
1482///
1483/// # Usage
1484///
1485/// ```rust
1486/// use hyperlane::*;
1487/// use hyperlane_macros::*;
1488///
1489/// #[request_cookie("session_id" => session_cookie_opt)]
1490/// async fn handle_with_session(ctx: Context) {
1491/// if let Some(session) = session_cookie_opt {
1492/// // Use the session cookie value
1493/// }
1494/// }
1495/// ```
1496///
1497/// For specific cookie extraction, the variable will be available as `Option<String>`.
1498/// For all cookies extraction, the variable will be available as `String`.
1499#[proc_macro_attribute]
1500pub fn request_cookie(attr: TokenStream, item: TokenStream) -> TokenStream {
1501 request_cookie_macro(attr, item, Position::Prologue)
1502}
1503
1504/// Extracts all cookies as a raw string into a variable.
1505///
1506/// This attribute macro retrieves the entire Cookie header from the request and makes it
1507/// available as a String variable. If no Cookie header is present, an empty string is used.
1508///
1509/// # Usage
1510///
1511/// ```rust
1512/// use hyperlane::*;
1513/// use hyperlane_macros::*;
1514///
1515/// #[request_cookies(cookie_value)]
1516/// async fn handle_with_cookies(ctx: Context) {
1517/// // Use the cookie value
1518/// if !cookie_value.is_empty() {
1519/// // Process cookie data
1520/// }
1521/// }
1522/// ```
1523///
1524/// The macro accepts a variable name that will contain the Cookie header value.
1525/// The variable will be available as a String in the function scope.
1526#[proc_macro_attribute]
1527pub fn request_cookies(attr: TokenStream, item: TokenStream) -> TokenStream {
1528 request_cookies_macro(attr, item, Position::Prologue)
1529}
1530
1531/// Extracts the HTTP request version into a variable.
1532///
1533/// This attribute macro retrieves the HTTP version from the request and makes it
1534/// available as a variable. The version represents the HTTP protocol version used.
1535///
1536/// # Usage
1537///
1538/// ```rust
1539/// use hyperlane::*;
1540/// use hyperlane_macros::*;
1541///
1542/// #[request_version(http_version)]
1543/// async fn handle_with_version(ctx: Context) {
1544/// // Use the HTTP version
1545/// }
1546/// ```
1547///
1548/// The macro accepts a variable name that will contain the HTTP request version.
1549/// The variable will be available as a RequestVersion type in the function scope.
1550#[proc_macro_attribute]
1551pub fn request_version(attr: TokenStream, item: TokenStream) -> TokenStream {
1552 request_version_macro(attr, item, Position::Prologue)
1553}
1554
1555/// Extracts the HTTP request path into a variable.
1556///
1557/// This attribute macro retrieves the request path from the HTTP request and makes it
1558/// available as a variable. The path represents the URL path portion of the request.
1559///
1560/// # Usage
1561///
1562/// ```rust
1563/// use hyperlane::*;
1564/// use hyperlane_macros::*;
1565///
1566/// #[request_path(request_path)]
1567/// async fn handle_with_path(ctx: Context) {
1568/// // Use the request path
1569/// if request_path.starts_with("/api/") {
1570/// // Handle API requests
1571/// }
1572/// }
1573/// ```
1574///
1575/// The macro accepts a variable name that will contain the HTTP request path.
1576/// The variable will be available as a RequestPath type in the function scope.
1577#[proc_macro_attribute]
1578pub fn request_path(attr: TokenStream, item: TokenStream) -> TokenStream {
1579 request_path_macro(attr, item, Position::Prologue)
1580}
1581
1582/// Creates a new instance of a specified type with a given variable name.
1583///
1584/// This attribute macro generates an instance initialization at the beginning of the function.
1585///
1586/// # Usage
1587///
1588/// ```rust
1589/// use hyperlane::*;
1590/// use hyperlane_macros::*;
1591///
1592/// #[hyperlane(server: Server)]
1593/// #[tokio::main]
1594/// async fn main() {
1595/// // `server` is now available as: `let server: Server = Server::new().await;`
1596/// // The function body can now use `server`.
1597/// }
1598/// ```
1599///
1600/// The macro accepts a `variable_name: Type` pair.
1601/// The variable will be available as an instance of the specified type in the function scope.
1602#[proc_macro_attribute]
1603pub fn hyperlane(attr: TokenStream, item: TokenStream) -> TokenStream {
1604 hyperlane_macro(attr, item)
1605}
1606
1607/// Registers a function as a route handler.
1608///
1609/// This attribute macro registers the decorated function as a route handler for a given path.
1610/// This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
1611///
1612/// # Usage
1613///
1614/// ```rust
1615/// use hyperlane::*;
1616/// use hyperlane_macros::*;
1617///
1618/// #[route("/")]
1619/// async fn route(ctx: Context) {
1620/// // function body
1621/// }
1622/// ```
1623///
1624/// # Parameters
1625///
1626/// - `path`: String literal defining the route path
1627///
1628/// # Dependencies
1629///
1630/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
1631#[proc_macro_attribute]
1632pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
1633 route_macro(attr, item)
1634}
1635
1636/// Registers a function as a request middleware.
1637///
1638/// This attribute macro registers the decorated function to be executed as a middleware
1639/// for incoming requests. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
1640///
1641/// # Note
1642///
1643/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
1644///
1645/// # Usage
1646///
1647/// ```rust
1648/// use hyperlane::*;
1649/// use hyperlane_macros::*;
1650///
1651/// #[request_middleware]
1652/// #[request_middleware(1)]
1653/// #[request_middleware("2")]
1654/// async fn log_request(ctx: Context) {
1655/// // Middleware logic
1656/// }
1657/// ```
1658///
1659/// # Dependencies
1660///
1661/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
1662#[proc_macro_attribute]
1663pub fn request_middleware(attr: TokenStream, item: TokenStream) -> TokenStream {
1664 request_middleware_macro(attr, item)
1665}
1666
1667/// Registers a function as a response middleware.
1668///
1669/// This attribute macro registers the decorated function to be executed as a middleware
1670/// for outgoing responses. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
1671///
1672/// # Note
1673///
1674/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
1675///
1676/// # Usage
1677///
1678/// ```rust
1679/// use hyperlane::*;
1680/// use hyperlane_macros::*;
1681///
1682/// #[response_middleware]
1683/// #[response_middleware(1)]
1684/// #[response_middleware("2")]
1685/// async fn add_custom_header(ctx: Context) {
1686/// // Middleware logic
1687/// }
1688/// ```
1689///
1690/// # Dependencies
1691///
1692/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
1693#[proc_macro_attribute]
1694pub fn response_middleware(attr: TokenStream, item: TokenStream) -> TokenStream {
1695 response_middleware_macro(attr, item)
1696}
1697
1698/// Registers a function as a panic hook.
1699///
1700/// This attribute macro registers the decorated function to handle panics that occur
1701/// during request processing. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
1702///
1703/// # Note
1704///
1705/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
1706///
1707/// # Usage
1708///
1709/// ```rust
1710/// use hyperlane::*;
1711/// use hyperlane_macros::*;
1712///
1713/// #[panic_hook]
1714/// #[panic_hook(1)]
1715/// #[panic_hook("2")]
1716/// async fn handle_panic(ctx: Context) {
1717/// // Panic handling logic
1718/// }
1719/// ```
1720///
1721/// # Dependencies
1722///
1723/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
1724#[proc_macro_attribute]
1725pub fn panic_hook(attr: TokenStream, item: TokenStream) -> TokenStream {
1726 panic_hook_macro(attr, item)
1727}
1728
1729/// Injects a list of macros before the decorated function.
1730///
1731/// The macros are applied in head-insertion order, meaning the first macro in the list
1732/// is the outermost macro.
1733///
1734/// # Usage
1735///
1736/// ```rust
1737/// use hyperlane::*;
1738/// use hyperlane_macros::*;
1739///
1740/// #[prologue_macros(post, send)]
1741/// async fn handler(ctx: Context) {
1742/// // ...
1743/// }
1744/// ```
1745#[proc_macro_attribute]
1746pub fn prologue_macros(attr: TokenStream, item: TokenStream) -> TokenStream {
1747 prologue_macros_macro(attr, item)
1748}
1749
1750/// Injects a list of macros after the decorated function.
1751///
1752/// The macros are applied in tail-insertion order, meaning the last macro in the list
1753/// is the outermost macro.
1754///
1755/// # Usage
1756///
1757/// ```rust
1758/// use hyperlane::*;
1759/// use hyperlane_macros::*;
1760///
1761/// #[epilogue_macros(post, send)]
1762/// async fn handler(ctx: Context) {
1763/// // ...
1764/// }
1765/// ```
1766#[proc_macro_attribute]
1767pub fn epilogue_macros(attr: TokenStream, item: TokenStream) -> TokenStream {
1768 epilogue_macros_macro(attr, item)
1769}
1770
1771/// Sends only the response body with data after function execution.
1772///
1773/// This attribute macro ensures that only the response body is automatically sent
1774/// to the client after the function completes, handling request headers separately,
1775/// with the specified data.
1776///
1777/// # Usage
1778///
1779/// ```rust
1780/// use hyperlane::*;
1781/// use hyperlane_macros::*;
1782///
1783/// #[send_body_with_data("Response body content")]
1784/// async fn send_body_with_data_handler(ctx: Context) {
1785/// // Response body is automatically sent with the specified data after function returns
1786/// }
1787/// ```
1788///
1789/// The macro accepts data to send and should be applied to async functions
1790/// that accept a `Context` parameter.
1791#[proc_macro_attribute]
1792pub fn send_body_with_data(attr: TokenStream, item: TokenStream) -> TokenStream {
1793 send_body_with_data_macro(attr, item, Position::Epilogue)
1794}
1795
1796/// Wraps function body with WebSocket stream processing.
1797///
1798/// This attribute macro generates code that wraps the function body with a check to see if
1799/// data can be read from a WebSocket stream. The function body is only executed
1800/// if data is successfully read from the stream.
1801///
1802/// This attribute macro generates code that wraps the function body with a check to see if
1803/// data can be read from a WebSocket stream. The function body is only executed
1804/// if data is successfully read from the stream.
1805///
1806/// # Arguments
1807///
1808/// - `TokenStream`: The buffer to read from the WebSocket stream.
1809/// - `TokenStream`: The function item to be modified
1810///
1811/// # Returns
1812///
1813/// Returns a TokenStream containing the modified function with WebSocket stream processing logic.
1814///
1815/// # Examples
1816///
1817/// Using no parameters (default buffer size):
1818/// ```rust
1819/// use hyperlane::*;
1820/// use hyperlane_macros::*;
1821///
1822/// #[http_from_stream]
1823/// async fn handle_data(ctx: Context) {
1824/// // Process data from HTTP stream with default buffer size
1825/// }
1826/// ```
1827///
1828/// Basic usage with buffer size:
1829/// ```rust
1830/// use hyperlane::*;
1831/// use hyperlane_macros::*;
1832///
1833/// #[ws_from_stream(1024)]
1834/// async fn handle_data(ctx: Context) {
1835/// // Process data from stream with 1024 byte buffer
1836/// }
1837/// ```
1838///
1839/// Using a variable name for the data:
1840/// ```rust
1841/// use hyperlane::*;
1842/// use hyperlane_macros::*;
1843///
1844/// #[ws_from_stream(data)]
1845/// async fn handle_data(ctx: Context) {
1846/// // Data will be available in the `data` variable
1847/// }
1848/// ```
1849///
1850/// Using both buffer size and variable name:
1851/// ```rust
1852/// use hyperlane::*;
1853/// use hyperlane_macros::*;
1854///
1855/// #[ws_from_stream(1024, payload)]
1856/// async fn handle_large_data(ctx: Context) {
1857/// // Process large data with 1024 byte buffer, available in `payload` variable
1858/// }
1859/// ```
1860///
1861/// Reversing buffer size and variable name:
1862/// ```rust
1863/// use hyperlane::*;
1864/// use hyperlane_macros::*;
1865///
1866/// #[ws_from_stream(payload, 1024)]
1867/// async fn handle_reversed_data(ctx: Context) {
1868/// // Process data with 1024 byte buffer, available in `payload` variable
1869/// }
1870/// ```
1871#[proc_macro_attribute]
1872pub fn ws_from_stream(attr: TokenStream, item: TokenStream) -> TokenStream {
1873 ws_from_stream_macro(attr, item)
1874}
1875
1876/// Wraps function body with HTTP stream processing.
1877///
1878/// This attribute macro generates code that wraps the function body with a check to see if
1879/// data can be read from an HTTP stream. The function body is only executed
1880/// if data is successfully read from the stream.
1881///
1882/// This attribute macro generates code that wraps the function body with a check to see if
1883/// data can be read from an HTTP stream. The function body is only executed
1884/// if data is successfully read from the stream.
1885///
1886/// # Arguments
1887///
1888/// - `TokenStream`: The buffer to read from the HTTP stream.
1889/// - `TokenStream`: The function item to be modified
1890///
1891/// # Returns
1892///
1893/// Returns a TokenStream containing the modified function with HTTP stream processing logic.
1894///
1895/// # Examples
1896///
1897/// Using no parameters (default buffer size):
1898/// ```rust
1899/// use hyperlane::*;
1900/// use hyperlane_macros::*;
1901///
1902/// #[http_from_stream]
1903/// async fn handle_data(ctx: Context) {
1904/// // Process data from HTTP stream with default buffer size
1905/// }
1906/// ```
1907///
1908/// Basic usage with buffer size:
1909/// ```rust
1910/// use hyperlane::*;
1911/// use hyperlane_macros::*;
1912///
1913/// #[http_from_stream(1024)]
1914/// async fn handle_data(ctx: Context) {
1915/// // Process data from stream with 1024 byte buffer
1916/// }
1917/// ```
1918///
1919/// Using a variable name for the data:
1920/// ```rust
1921/// use hyperlane::*;
1922/// use hyperlane_macros::*;
1923///
1924/// #[http_from_stream(data)]
1925/// async fn handle_data(ctx: Context) {
1926/// // Data will be available in the `data` variable
1927/// }
1928/// ```
1929///
1930/// Using both buffer size and variable name:
1931/// ```rust
1932/// use hyperlane::*;
1933/// use hyperlane_macros::*;
1934///
1935/// #[http_from_stream(1024, payload)]
1936/// async fn handle_large_data(ctx: Context) {
1937/// // Process large data with 1024 byte buffer, available in `payload` variable
1938/// }
1939/// ```
1940#[proc_macro_attribute]
1941pub fn http_from_stream(attr: TokenStream, item: TokenStream) -> TokenStream {
1942 http_from_stream_macro(attr, item)
1943}