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 a specified function before the main handler function.
1122///
1123/// This attribute macro configures a pre-execution hook that runs before the main function logic.
1124/// The specified hook function will be called first, 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_handler(ctx: Context) {
1134/// // Pre-execution logic
1135/// }
1136///
1137/// #[prologue_hook(prologue_handler)]
1138/// async fn main_handler(ctx: Context) {
1139/// // Main function logic (runs after prologue_handler)
1140/// }
1141/// ```
1142///
1143/// The macro accepts a function name as parameter. Both the hook function and main function
1144/// must accept a `Context` parameter. Avoid combining this macro with other macros on the
1145/// same function to prevent macro expansion conflicts.
1146#[proc_macro_attribute]
1147pub fn prologue_hook(attr: TokenStream, item: TokenStream) -> TokenStream {
1148 prologue_hook_macro(attr, item, Position::Prologue)
1149}
1150
1151/// Executes a specified function after the main handler function.
1152///
1153/// This attribute macro configures a post-execution hook that runs after the main function logic.
1154/// The main function will execute first, followed by the specified hook function.
1155///
1156/// # Usage
1157///
1158/// ```rust
1159/// use hyperlane::*;
1160/// use hyperlane_macros::*;
1161///
1162/// #[send]
1163/// async fn epilogue_handler(ctx: Context) {
1164/// // Post-execution logic
1165/// }
1166///
1167/// #[epilogue_hook(epilogue_handler)]
1168/// async fn main_handler(ctx: Context) {
1169/// // Main function logic (runs before epilogue_handler)
1170/// }
1171/// ```
1172///
1173/// The macro accepts a function name as parameter. Both the hook function and main function
1174/// must accept a `Context` parameter. Avoid combining this macro with other macros on the
1175/// same function to prevent macro expansion conflicts.
1176#[proc_macro_attribute]
1177pub fn epilogue_hook(attr: TokenStream, item: TokenStream) -> TokenStream {
1178 epilogue_hook_macro(attr, item, Position::Epilogue)
1179}
1180
1181/// Extracts the raw request body into a specified variable.
1182///
1183/// This attribute macro extracts the raw request body content into a variable
1184/// with the fixed type `RequestBody`. The body content is not parsed or deserialized.
1185///
1186/// # Usage
1187///
1188/// ```rust
1189/// use hyperlane::*;
1190/// use hyperlane_macros::*;
1191///
1192/// #[request_body(raw_body)]
1193/// async fn handle_raw_body(ctx: Context) {
1194/// // Use the raw request body
1195/// let body_content = raw_body;
1196/// }
1197/// ```
1198///
1199/// The macro accepts only a variable name. The variable will be available
1200/// in the function scope as a `RequestBody` type.
1201#[proc_macro_attribute]
1202pub fn request_body(attr: TokenStream, item: TokenStream) -> TokenStream {
1203 request_body_macro(attr, item, Position::Prologue)
1204}
1205
1206/// Parses the request body as JSON into a specified variable and type.
1207///
1208/// This attribute macro extracts and deserializes the request body content as JSON into a variable
1209/// with the specified type. The body content is parsed as JSON using serde.
1210///
1211/// # Usage
1212///
1213/// ```rust
1214/// use hyperlane::*;
1215/// use hyperlane_macros::*;
1216/// use serde::Deserialize;
1217///
1218/// #[derive(Deserialize, Clone)]
1219/// struct UserData {
1220/// name: String,
1221/// age: u32,
1222/// }
1223///
1224/// #[request_body_json(user_data: UserData)]
1225/// async fn handle_user(ctx: Context) {
1226/// if let Ok(data) = user_data {
1227/// // Use the parsed user data
1228/// }
1229/// }
1230/// ```
1231///
1232/// The macro accepts a variable name and type in the format `variable_name: Type`.
1233/// The variable will be available in the function scope as a `Result<Type, JsonError>`.
1234#[proc_macro_attribute]
1235pub fn request_body_json(attr: TokenStream, item: TokenStream) -> TokenStream {
1236 request_body_json_macro(attr, item, Position::Prologue)
1237}
1238
1239/// Extracts a specific attribute value into a variable.
1240///
1241/// This attribute macro retrieves a specific attribute by key and makes it available
1242/// as a typed variable from the request context.
1243///
1244/// # Usage
1245///
1246/// ```rust
1247/// use hyperlane::*;
1248/// use hyperlane_macros::*;
1249/// use serde::Deserialize;
1250///
1251/// const USER_KEY: &str = "user_data";
1252///
1253/// #[derive(Deserialize, Clone)]
1254/// struct User {
1255/// id: u64,
1256/// name: String,
1257/// }
1258///
1259/// #[attribute(USER_KEY => user: User)]
1260/// async fn handle_with_attribute(ctx: Context) {
1261/// if let Some(user_data) = user {
1262/// // Use the extracted attribute
1263/// }
1264/// }
1265/// ```
1266///
1267/// The macro accepts a key-to-variable mapping in the format `key => variable_name: Type`.
1268/// The variable will be available as an `Option<Type>` in the function scope.
1269#[proc_macro_attribute]
1270pub fn attribute(attr: TokenStream, item: TokenStream) -> TokenStream {
1271 attribute_macro(attr, item, Position::Prologue)
1272}
1273
1274/// Extracts all attributes into a HashMap variable.
1275///
1276/// This attribute macro retrieves all available attributes from the request context
1277/// and makes them available as a HashMap for comprehensive attribute access.
1278///
1279/// # Usage
1280///
1281/// ```rust
1282/// use hyperlane::*;
1283/// use hyperlane_macros::*;
1284///
1285/// #[attributes(all_attrs)]
1286/// async fn handle_with_all_attributes(ctx: Context) {
1287/// for (key, value) in all_attrs {
1288/// // Process each attribute
1289/// }
1290/// }
1291/// ```
1292///
1293/// The macro accepts a variable name that will contain a HashMap of all attributes.
1294/// The variable will be available as a HashMap in the function scope.
1295#[proc_macro_attribute]
1296pub fn attributes(attr: TokenStream, item: TokenStream) -> TokenStream {
1297 attributes_macro(attr, item, Position::Prologue)
1298}
1299
1300/// Extracts a specific route parameter into a variable.
1301///
1302/// This attribute macro retrieves a specific route parameter by key and makes it
1303/// available as a variable. Route parameters are extracted from the URL path segments.
1304///
1305/// # Usage
1306///
1307/// ```rust
1308/// use hyperlane::*;
1309/// use hyperlane_macros::*;
1310///
1311/// // For route like "/users/{id}"
1312/// #[route_param("id" => user_id)]
1313/// async fn get_user(ctx: Context) {
1314/// if let Some(id) = user_id {
1315/// // Use the route parameter
1316/// }
1317/// }
1318/// ```
1319///
1320/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
1321/// The variable will be available as an `Option<String>` in the function scope.
1322#[proc_macro_attribute]
1323pub fn route_param(attr: TokenStream, item: TokenStream) -> TokenStream {
1324 route_param_macro(attr, item, Position::Prologue)
1325}
1326
1327/// Extracts all route parameters into a collection variable.
1328///
1329/// This attribute macro retrieves all available route parameters from the URL path
1330/// and makes them available as a collection for comprehensive route parameter access.
1331///
1332/// # Usage
1333///
1334/// ```rust
1335/// use hyperlane::*;
1336/// use hyperlane_macros::*;
1337///
1338/// // For route like "/users/{id}/posts/{epilogue_id}"
1339/// #[route_params(params)]
1340/// async fn handle_nested_route(ctx: Context) {
1341/// for (key, value) in params {
1342/// // Process each route parameter
1343/// }
1344/// }
1345/// ```
1346///
1347/// The macro accepts a variable name that will contain all route parameters.
1348/// The variable will be available as a collection in the function scope.
1349#[proc_macro_attribute]
1350pub fn route_params(attr: TokenStream, item: TokenStream) -> TokenStream {
1351 route_params_macro(attr, item, Position::Prologue)
1352}
1353
1354/// Extracts a specific request query parameter into a variable.
1355///
1356/// This attribute macro retrieves a specific request query parameter by key and makes it
1357/// available as a variable. Query parameters are extracted from the URL request query string.
1358///
1359/// # Usage
1360///
1361/// ```rust
1362/// use hyperlane::*;
1363/// use hyperlane_macros::*;
1364///
1365/// // For URL like "/search?q=rust&limit=10"
1366/// #[request_query("q" => search_term)]
1367/// async fn search(ctx: Context) {
1368/// if let Some(term) = search_term {
1369/// // Use the request query parameter
1370/// }
1371/// }
1372/// ```
1373///
1374/// The macro accepts a key-to-variable mapping in the format `"key" => variable_name`.
1375/// The variable will be available as an `Option<String>` in the function scope.
1376#[proc_macro_attribute]
1377pub fn request_query(attr: TokenStream, item: TokenStream) -> TokenStream {
1378 request_query_macro(attr, item, Position::Prologue)
1379}
1380
1381/// Extracts all request query parameters into a collection variable.
1382///
1383/// This attribute macro retrieves all available request query parameters from the URL request query string
1384/// and makes them available as a collection for comprehensive request query parameter access.
1385///
1386/// # Usage
1387///
1388/// ```rust
1389/// use hyperlane::*;
1390/// use hyperlane_macros::*;
1391///
1392/// // For URL like "/search?q=rust&limit=10&sort=date"
1393/// #[request_querys(all_params)]
1394/// async fn search_with_params(ctx: Context) {
1395/// for (key, value) in all_params {
1396/// // Process each request query parameter
1397/// }
1398/// }
1399/// ```
1400///
1401/// The macro accepts a variable name that will contain all request query parameters.
1402/// The variable will be available as a collection in the function scope.
1403#[proc_macro_attribute]
1404pub fn request_querys(attr: TokenStream, item: TokenStream) -> TokenStream {
1405 request_querys_macro(attr, item, Position::Prologue)
1406}
1407
1408/// Extracts a specific HTTP request header into a variable.
1409///
1410/// This attribute macro retrieves a specific HTTP request header by name and makes it
1411/// available as a variable. Header values are extracted from the request request headers collection.
1412///
1413/// # Usage
1414///
1415/// ```rust
1416/// use hyperlane::*;
1417/// use hyperlane_macros::*;
1418///
1419/// #[request_header(HOST => host_request_header)]
1420/// async fn handle_with_host(ctx: Context) {
1421/// if let Some(host) = host_request_header {
1422/// // Use the host request_header value
1423/// }
1424/// }
1425///
1426/// #[request_header("Content-Type" => content_type)]
1427/// async fn handle_with_content_type(ctx: Context) {
1428/// if let Some(ct) = content_type {
1429/// // Use the content type request_header
1430/// }
1431/// }
1432/// ```
1433///
1434/// The macro accepts a request header name-to-variable mapping in the format `HEADER_NAME => variable_name`
1435/// or `"Header-Name" => variable_name`. The variable will be available as an `Option<String>`.
1436#[proc_macro_attribute]
1437pub fn request_header(attr: TokenStream, item: TokenStream) -> TokenStream {
1438 request_header_macro(attr, item, Position::Prologue)
1439}
1440
1441/// Extracts all HTTP request headers into a collection variable.
1442///
1443/// This attribute macro retrieves all available HTTP request headers from the request
1444/// and makes them available as a collection for comprehensive request header access.
1445///
1446/// # Usage
1447///
1448/// ```rust
1449/// use hyperlane::*;
1450/// use hyperlane_macros::*;
1451///
1452/// #[request_headers(all_request_headers)]
1453/// async fn handle_with_all_request_headers(ctx: Context) {
1454/// for (name, value) in all_request_headers {
1455/// // Process each request_header
1456/// }
1457/// }
1458/// ```
1459///
1460/// The macro accepts a variable name that will contain all HTTP request headers.
1461/// The variable will be available as a collection in the function scope.
1462#[proc_macro_attribute]
1463pub fn request_headers(attr: TokenStream, item: TokenStream) -> TokenStream {
1464 request_headers_macro(attr, item, Position::Prologue)
1465}
1466
1467/// Extracts a specific cookie value or all cookies into a variable.
1468///
1469/// This attribute macro supports two syntaxes:
1470/// 1. `cookie(key => variable_name)` - Extract a specific cookie value by key
1471/// 2. `cookie(variable_name)` - Extract all cookies as a raw string
1472///
1473/// # Usage
1474///
1475/// ```rust
1476/// use hyperlane::*;
1477/// use hyperlane_macros::*;
1478///
1479/// #[request_cookie("session_id" => session_cookie_opt)]
1480/// async fn handle_with_session(ctx: Context) {
1481/// if let Some(session) = session_cookie_opt {
1482/// // Use the session cookie value
1483/// }
1484/// }
1485/// ```
1486///
1487/// For specific cookie extraction, the variable will be available as `Option<String>`.
1488/// For all cookies extraction, the variable will be available as `String`.
1489#[proc_macro_attribute]
1490pub fn request_cookie(attr: TokenStream, item: TokenStream) -> TokenStream {
1491 request_cookie_macro(attr, item, Position::Prologue)
1492}
1493
1494/// Extracts all cookies as a raw string into a variable.
1495///
1496/// This attribute macro retrieves the entire Cookie header from the request and makes it
1497/// available as a String variable. If no Cookie header is present, an empty string is used.
1498///
1499/// # Usage
1500///
1501/// ```rust
1502/// use hyperlane::*;
1503/// use hyperlane_macros::*;
1504///
1505/// #[request_cookies(cookie_value)]
1506/// async fn handle_with_cookies(ctx: Context) {
1507/// // Use the cookie value
1508/// if !cookie_value.is_empty() {
1509/// // Process cookie data
1510/// }
1511/// }
1512/// ```
1513///
1514/// The macro accepts a variable name that will contain the Cookie header value.
1515/// The variable will be available as a String in the function scope.
1516#[proc_macro_attribute]
1517pub fn request_cookies(attr: TokenStream, item: TokenStream) -> TokenStream {
1518 request_cookies_macro(attr, item, Position::Prologue)
1519}
1520
1521/// Extracts the HTTP request version into a variable.
1522///
1523/// This attribute macro retrieves the HTTP version from the request and makes it
1524/// available as a variable. The version represents the HTTP protocol version used.
1525///
1526/// # Usage
1527///
1528/// ```rust
1529/// use hyperlane::*;
1530/// use hyperlane_macros::*;
1531///
1532/// #[request_version(http_version)]
1533/// async fn handle_with_version(ctx: Context) {
1534/// // Use the HTTP version
1535/// }
1536/// ```
1537///
1538/// The macro accepts a variable name that will contain the HTTP request version.
1539/// The variable will be available as a RequestVersion type in the function scope.
1540#[proc_macro_attribute]
1541pub fn request_version(attr: TokenStream, item: TokenStream) -> TokenStream {
1542 request_version_macro(attr, item, Position::Prologue)
1543}
1544
1545/// Extracts the HTTP request path into a variable.
1546///
1547/// This attribute macro retrieves the request path from the HTTP request and makes it
1548/// available as a variable. The path represents the URL path portion of the request.
1549///
1550/// # Usage
1551///
1552/// ```rust
1553/// use hyperlane::*;
1554/// use hyperlane_macros::*;
1555///
1556/// #[request_path(request_path)]
1557/// async fn handle_with_path(ctx: Context) {
1558/// // Use the request path
1559/// if request_path.starts_with("/api/") {
1560/// // Handle API requests
1561/// }
1562/// }
1563/// ```
1564///
1565/// The macro accepts a variable name that will contain the HTTP request path.
1566/// The variable will be available as a RequestPath type in the function scope.
1567#[proc_macro_attribute]
1568pub fn request_path(attr: TokenStream, item: TokenStream) -> TokenStream {
1569 request_path_macro(attr, item, Position::Prologue)
1570}
1571
1572/// Creates a new instance of a specified type with a given variable name.
1573///
1574/// This attribute macro generates an instance initialization at the beginning of the function.
1575///
1576/// # Usage
1577///
1578/// ```rust
1579/// use hyperlane::*;
1580/// use hyperlane_macros::*;
1581///
1582/// #[hyperlane(server: Server)]
1583/// #[tokio::main]
1584/// async fn main() {
1585/// // `server` is now available as: `let server: Server = Server::new().await;`
1586/// // The function body can now use `server`.
1587/// }
1588/// ```
1589///
1590/// The macro accepts a `variable_name: Type` pair.
1591/// The variable will be available as an instance of the specified type in the function scope.
1592#[proc_macro_attribute]
1593pub fn hyperlane(attr: TokenStream, item: TokenStream) -> TokenStream {
1594 hyperlane_macro(attr, item)
1595}
1596
1597/// Registers a function as a route handler.
1598///
1599/// This attribute macro registers the decorated function as a route handler for a given path.
1600/// This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
1601///
1602/// # Usage
1603///
1604/// ```rust
1605/// use hyperlane::*;
1606/// use hyperlane_macros::*;
1607///
1608/// #[route("/")]
1609/// async fn route(ctx: Context) {
1610/// // function body
1611/// }
1612/// ```
1613///
1614/// # Parameters
1615///
1616/// - `path`: String literal defining the route path
1617///
1618/// # Dependencies
1619///
1620/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
1621#[proc_macro_attribute]
1622pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
1623 route_macro(attr, item)
1624}
1625
1626/// Registers a function as a request middleware.
1627///
1628/// This attribute macro registers the decorated function to be executed as a middleware
1629/// for incoming requests. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
1630///
1631/// # Note
1632///
1633/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
1634///
1635/// # Usage
1636///
1637/// ```rust
1638/// use hyperlane::*;
1639/// use hyperlane_macros::*;
1640///
1641/// #[request_middleware]
1642/// #[request_middleware(1)]
1643/// #[request_middleware("2")]
1644/// async fn log_request(ctx: Context) {
1645/// // Middleware logic
1646/// }
1647/// ```
1648///
1649/// # Dependencies
1650///
1651/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
1652#[proc_macro_attribute]
1653pub fn request_middleware(attr: TokenStream, item: TokenStream) -> TokenStream {
1654 request_middleware_macro(attr, item)
1655}
1656
1657/// Registers a function as a response middleware.
1658///
1659/// This attribute macro registers the decorated function to be executed as a middleware
1660/// for outgoing responses. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
1661///
1662/// # Note
1663///
1664/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
1665///
1666/// # Usage
1667///
1668/// ```rust
1669/// use hyperlane::*;
1670/// use hyperlane_macros::*;
1671///
1672/// #[response_middleware]
1673/// #[response_middleware(1)]
1674/// #[response_middleware("2")]
1675/// async fn add_custom_header(ctx: Context) {
1676/// // Middleware logic
1677/// }
1678/// ```
1679///
1680/// # Dependencies
1681///
1682/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
1683#[proc_macro_attribute]
1684pub fn response_middleware(attr: TokenStream, item: TokenStream) -> TokenStream {
1685 response_middleware_macro(attr, item)
1686}
1687
1688/// Registers a function as a panic hook.
1689///
1690/// This attribute macro registers the decorated function to handle panics that occur
1691/// during request processing. This macro requires the `#[hyperlane(server: Server)]` macro to be used to define the server instance.
1692///
1693/// # Note
1694///
1695/// If an order parameter is not specified, the hook will have a higher priority than hooks with a specified order.
1696///
1697/// # Usage
1698///
1699/// ```rust
1700/// use hyperlane::*;
1701/// use hyperlane_macros::*;
1702///
1703/// #[panic_hook]
1704/// #[panic_hook(1)]
1705/// #[panic_hook("2")]
1706/// async fn handle_panic(ctx: Context) {
1707/// // Panic handling logic
1708/// }
1709/// ```
1710///
1711/// # Dependencies
1712///
1713/// This macro depends on the `#[hyperlane(server: Server)]` macro to define the server instance.
1714#[proc_macro_attribute]
1715pub fn panic_hook(attr: TokenStream, item: TokenStream) -> TokenStream {
1716 panic_hook_macro(attr, item)
1717}
1718
1719/// Injects a list of macros before the decorated function.
1720///
1721/// The macros are applied in head-insertion order, meaning the first macro in the list
1722/// is the outermost macro.
1723///
1724/// # Usage
1725///
1726/// ```rust
1727/// use hyperlane::*;
1728/// use hyperlane_macros::*;
1729///
1730/// #[prologue_macro(post, send)]
1731/// async fn handler(ctx: Context) {
1732/// // ...
1733/// }
1734/// ```
1735#[proc_macro_attribute]
1736pub fn prologue_macro(attr: TokenStream, item: TokenStream) -> TokenStream {
1737 prologue_hooks_macro(attr, item)
1738}
1739
1740/// Injects a list of macros after the decorated function.
1741///
1742/// The macros are applied in tail-insertion order, meaning the last macro in the list
1743/// is the outermost macro.
1744///
1745/// # Usage
1746///
1747/// ```rust
1748/// use hyperlane::*;
1749/// use hyperlane_macros::*;
1750///
1751/// #[epilogue_macro(post, send)]
1752/// async fn handler(ctx: Context) {
1753/// // ...
1754/// }
1755/// ```
1756#[proc_macro_attribute]
1757pub fn epilogue_macro(attr: TokenStream, item: TokenStream) -> TokenStream {
1758 epilogue_hooks_macro(attr, item)
1759}
1760
1761/// Sends only the response body with data after function execution.
1762///
1763/// This attribute macro ensures that only the response body is automatically sent
1764/// to the client after the function completes, handling request headers separately,
1765/// with the specified data.
1766///
1767/// # Usage
1768///
1769/// ```rust
1770/// use hyperlane::*;
1771/// use hyperlane_macros::*;
1772///
1773/// #[send_body_with_data("Response body content")]
1774/// async fn send_body_with_data_handler(ctx: Context) {
1775/// // Response body is automatically sent with the specified data after function returns
1776/// }
1777/// ```
1778///
1779/// The macro accepts data to send and should be applied to async functions
1780/// that accept a `Context` parameter.
1781#[proc_macro_attribute]
1782pub fn send_body_with_data(attr: TokenStream, item: TokenStream) -> TokenStream {
1783 send_body_with_data_macro(attr, item, Position::Epilogue)
1784}
1785
1786/// Wraps function body with WebSocket stream processing.
1787///
1788/// This attribute macro generates code that wraps the function body with a check to see if
1789/// data can be read from a WebSocket stream. The function body is only executed
1790/// if data is successfully read from the stream.
1791///
1792/// This attribute macro generates code that wraps the function body with a check to see if
1793/// data can be read from a WebSocket stream. The function body is only executed
1794/// if data is successfully read from the stream.
1795///
1796/// # Arguments
1797///
1798/// - `TokenStream`: The buffer to read from the WebSocket stream.
1799/// - `TokenStream`: The function item to be modified
1800///
1801/// # Returns
1802///
1803/// Returns a TokenStream containing the modified function with WebSocket stream processing logic.
1804///
1805/// # Examples
1806///
1807/// Using no parameters (default buffer size):
1808/// ```rust
1809/// use hyperlane::*;
1810/// use hyperlane_macros::*;
1811///
1812/// #[http_from_stream]
1813/// async fn handle_data(ctx: Context) {
1814/// // Process data from HTTP stream with default buffer size
1815/// }
1816/// ```
1817///
1818/// Basic usage with buffer size:
1819/// ```rust
1820/// use hyperlane::*;
1821/// use hyperlane_macros::*;
1822///
1823/// #[ws_from_stream(1024)]
1824/// async fn handle_data(ctx: Context) {
1825/// // Process data from stream with 1024 byte buffer
1826/// }
1827/// ```
1828///
1829/// Using a variable name for the data:
1830/// ```rust
1831/// use hyperlane::*;
1832/// use hyperlane_macros::*;
1833///
1834/// #[ws_from_stream(data)]
1835/// async fn handle_data(ctx: Context) {
1836/// // Data will be available in the `data` variable
1837/// }
1838/// ```
1839///
1840/// Using both buffer size and variable name:
1841/// ```rust
1842/// use hyperlane::*;
1843/// use hyperlane_macros::*;
1844///
1845/// #[ws_from_stream(1024, payload)]
1846/// async fn handle_large_data(ctx: Context) {
1847/// // Process large data with 1024 byte buffer, available in `payload` variable
1848/// }
1849/// ```
1850///
1851/// Reversing buffer size and variable name:
1852/// ```rust
1853/// use hyperlane::*;
1854/// use hyperlane_macros::*;
1855///
1856/// #[ws_from_stream(payload, 1024)]
1857/// async fn handle_reversed_data(ctx: Context) {
1858/// // Process data with 1024 byte buffer, available in `payload` variable
1859/// }
1860/// ```
1861#[proc_macro_attribute]
1862pub fn ws_from_stream(attr: TokenStream, item: TokenStream) -> TokenStream {
1863 ws_from_stream_macro(attr, item)
1864}
1865
1866/// Wraps function body with HTTP stream processing.
1867///
1868/// This attribute macro generates code that wraps the function body with a check to see if
1869/// data can be read from an HTTP stream. The function body is only executed
1870/// if data is successfully read from the stream.
1871///
1872/// This attribute macro generates code that wraps the function body with a check to see if
1873/// data can be read from an HTTP stream. The function body is only executed
1874/// if data is successfully read from the stream.
1875///
1876/// # Arguments
1877///
1878/// - `TokenStream`: The buffer to read from the HTTP stream.
1879/// - `TokenStream`: The function item to be modified
1880///
1881/// # Returns
1882///
1883/// Returns a TokenStream containing the modified function with HTTP stream processing logic.
1884///
1885/// # Examples
1886///
1887/// Using no parameters (default buffer size):
1888/// ```rust
1889/// use hyperlane::*;
1890/// use hyperlane_macros::*;
1891///
1892/// #[http_from_stream]
1893/// async fn handle_data(ctx: Context) {
1894/// // Process data from HTTP stream with default buffer size
1895/// }
1896/// ```
1897///
1898/// Basic usage with buffer size:
1899/// ```rust
1900/// use hyperlane::*;
1901/// use hyperlane_macros::*;
1902///
1903/// #[http_from_stream(1024)]
1904/// async fn handle_data(ctx: Context) {
1905/// // Process data from stream with 1024 byte buffer
1906/// }
1907/// ```
1908///
1909/// Using a variable name for the data:
1910/// ```rust
1911/// use hyperlane::*;
1912/// use hyperlane_macros::*;
1913///
1914/// #[http_from_stream(data)]
1915/// async fn handle_data(ctx: Context) {
1916/// // Data will be available in the `data` variable
1917/// }
1918/// ```
1919///
1920/// Using both buffer size and variable name:
1921/// ```rust
1922/// use hyperlane::*;
1923/// use hyperlane_macros::*;
1924///
1925/// #[http_from_stream(1024, payload)]
1926/// async fn handle_large_data(ctx: Context) {
1927/// // Process large data with 1024 byte buffer, available in `payload` variable
1928/// }
1929/// ```
1930#[proc_macro_attribute]
1931pub fn http_from_stream(attr: TokenStream, item: TokenStream) -> TokenStream {
1932 http_from_stream_macro(attr, item)
1933}