11use proc_macro:: TokenStream ;
2- use proc_macro2:: Span ;
32use proc_macro_error2:: emit_error;
43use quote:: { quote, ToTokens } ;
5- use serde :: { ser :: SerializeStruct , Serialize } ;
4+ use shuttle_ifc :: InfraAttrParser ;
65use syn:: {
7- parse:: { Parse , ParseStream } ,
8- parse_macro_input, parse_quote,
9- punctuated:: Punctuated ,
10- spanned:: Spanned ,
11- Attribute , Error , Expr , ExprLit , FnArg , Ident , ItemFn , Lit , LitStr , Pat , PatIdent , Path ,
6+ meta:: parser, parse:: Parse , parse_macro_input, parse_quote, punctuated:: Punctuated ,
7+ spanned:: Spanned , Attribute , Expr , ExprLit , FnArg , Ident , ItemFn , Lit , Pat , PatIdent , Path ,
128 ReturnType , Signature , Stmt , Token , Type , TypePath ,
139} ;
1410
15- const BUILD_MANIFEST_FILE : & str = ".shuttle/build_manifest.json" ;
16-
17- /// Configuration options for the `shuttle_runtime` macro.
18- ///
19- /// This struct represents the arguments that can be passed to the
20- /// `#[shuttle_runtime(...)]` attribute macro. It currently supports:
21- ///
22- /// - `instance_size`: An optional string literal that specifies the size of the
23- /// instance to use for deploying the application. For example, "xs" or "m".
24- ///
25- /// Example usage:
26- /// ```rust
27- /// #[shuttle_runtime(instance_size = "l")]
28- /// async fn main() -> ShuttleActix {
29- /// // ...
30- /// }
31- /// ```
32- #[ derive( Clone , Debug , Default ) ]
33- struct RuntimeMacroArgs {
34- instance_size : Option < LitStr > ,
35- }
36-
37- impl Serialize for RuntimeMacroArgs {
38- /// Serializes the RuntimeMacroArgs struct into JSON.
39- ///
40- /// This is used to write configuration to the build manifest file.
41- fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
42- where
43- S : serde:: Serializer ,
44- {
45- let len = self . instance_size . is_some ( ) as usize ;
46- let mut state = serializer. serialize_struct ( "RuntimeMacroArgs" , len) ?;
47- if let Some ( instance_size) = & self . instance_size {
48- state. serialize_field ( "instance_size" , & instance_size. value ( ) ) ?;
49- }
50-
51- state. end ( )
52- }
53- }
54-
55- impl Parse for RuntimeMacroArgs {
56- /// Parses the arguments provided to the `#[shuttle_runtime(...)]` attribute macro.
57- ///
58- /// This implementation accepts key-value pairs separated by commas, where:
59- /// - `instance_size`: The size of the instance to use for the application
60- ///
61- /// Returns a Result containing either the parsed RuntimeMacroArgs or a syntax error.
62- /// If an unrecognized key is provided, it will return an error with a helpful
63- /// message explaining the invalid key.
64- fn parse ( input : ParseStream ) -> syn:: Result < Self > {
65- let mut instance_size = None ;
66-
67- while !input. is_empty ( ) {
68- let key: Ident = input. parse ( ) ?;
69- input. parse :: < Token ! [ =] > ( ) ?;
70-
71- match key. to_string ( ) . as_str ( ) {
72- "instance_size" => {
73- instance_size = Some ( input. parse :: < LitStr > ( ) ?) ;
74- }
75- unknown_key => {
76- return Err ( syn:: Error :: new (
77- key. span ( ) ,
78- format ! (
79- "Invalid `shuttle_runtime` macro attribute key: '{}'" ,
80- unknown_key
81- ) ,
82- ) )
83- }
84- }
85-
86- if !input. is_empty ( ) {
87- input. parse :: < Token ! [ , ] > ( ) ?;
88- }
89- }
90-
91- Ok ( RuntimeMacroArgs { instance_size } )
92- }
93- }
94-
95- /// Entry point for the `#[shuttle_runtime]` attribute macro.
11+ /// Entrypoint for the `#[shuttle_runtime::main]` attribute macro.
9612///
9713/// This function processes the attribute arguments and the annotated function,
9814/// generating code that:
@@ -116,52 +32,10 @@ pub(crate) fn tokens(attr: TokenStream, item: TokenStream) -> TokenStream {
11632 let mut user_main_fn = parse_macro_input ! ( item as ItemFn ) ;
11733 let loader_runner = LoaderAndRunner :: from_item_fn ( & mut user_main_fn) ;
11834
119- // Start write build manifest - to be replaced by a syn parse stage
120- // --
121- let attr_ast = parse_macro_input ! ( attr as RuntimeMacroArgs ) ;
122-
123- let json_str = match serde_json:: to_string ( & attr_ast) . map_err ( |err| {
124- Error :: new (
125- user_main_fn. span ( ) ,
126- format ! ( "failed to serialize build manifest: {:?}" , err) ,
127- )
128- } ) {
129- Ok ( json) => json,
130- Err ( e) => return e. into_compile_error ( ) . into ( ) ,
131- } ;
132-
133- if let Some ( shuttle_dir) = std:: path:: Path :: new ( BUILD_MANIFEST_FILE ) . parent ( ) {
134- if !shuttle_dir. exists ( ) {
135- match std:: fs:: create_dir_all ( shuttle_dir) . map_err ( |err| {
136- Error :: new (
137- user_main_fn. span ( ) ,
138- format ! (
139- "failed to create shuttle directory: {:?}: {}" ,
140- shuttle_dir, err
141- ) ,
142- )
143- } ) {
144- Ok ( _) => ( ) ,
145- Err ( e) => return e. into_compile_error ( ) . into ( ) ,
146- } ;
147- }
148- }
149-
150- match std:: fs:: write ( BUILD_MANIFEST_FILE , json_str) . map_err ( |err| {
151- Error :: new (
152- user_main_fn. span ( ) ,
153- format ! (
154- "failed to write build manifest to '{}': {:?}" ,
155- BUILD_MANIFEST_FILE , err
156- ) ,
157- )
158- } ) {
159- Ok ( _) => ( ) ,
160- Err ( e) => return e. into_compile_error ( ) . into ( ) ,
161- } ;
162-
163- // End write build manifest
164- // --
35+ // parse infra in main attribute
36+ let mut infra_parser = InfraAttrParser :: default ( ) ;
37+ let meta_parser = parser ( |meta| infra_parser. parse_nested_meta ( meta) ) ;
38+ parse_macro_input ! ( attr with meta_parser) ;
16539
16640 Into :: into ( quote ! {
16741 fn main( ) {
@@ -252,9 +126,10 @@ impl LoaderAndRunner {
252126 // prefix the function name to allow any name, such as 'main'
253127 item_fn. sig . ident = Ident :: new (
254128 & format ! ( "__shuttle_{}" , item_fn. sig. ident) ,
255- Span :: call_site ( ) ,
129+ item_fn . sig . ident . span ( ) ,
256130 ) ;
257131
132+ // parse builders from function arguments
258133 let inputs: Vec < _ > = item_fn
259134 . sig
260135 . inputs
0 commit comments