@@ -50,6 +50,8 @@ limitations under the License.
5050extern crate proc_macro;
5151
5252use hyperlight_component_util:: * ;
53+ use syn:: parse:: { Parse , ParseStream } ;
54+ use syn:: { Ident , LitStr , Result , Token } ;
5355
5456/// Create host bindings for the wasm component type in the file
5557/// passed in (or `$WIT_WORLD`, if nothing is passed in). This will
@@ -66,11 +68,19 @@ use hyperlight_component_util::*;
6668#[ proc_macro]
6769pub fn host_bindgen ( input : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
6870 let _ = env_logger:: try_init ( ) ;
69- let path: Option < syn:: LitStr > = syn:: parse_macro_input!( input as Option <syn:: LitStr >) ;
70- let path = path
71- . map ( |x| x. value ( ) . into ( ) )
72- . unwrap_or_else ( || std:: env:: var_os ( "WIT_WORLD" ) . unwrap ( ) ) ;
73- util:: read_wit_type_from_file ( path, |kebab_name, ct| {
71+ let parsed_bindgen_input = syn:: parse_macro_input!( input as BindgenInputParams ) ;
72+ let path = parsed_bindgen_input. path . unwrap_or_else ( || {
73+ let wit_world_env = std:: env:: var_os ( "WIT_WORLD" ) ;
74+
75+ if let Some ( env) = wit_world_env {
76+ std:: path:: PathBuf :: from ( env)
77+ } else {
78+ std:: path:: PathBuf :: new ( )
79+ }
80+ } ) ;
81+ let world_name = parsed_bindgen_input. world_name ;
82+
83+ util:: read_wit_type_from_file ( path, world_name, |kebab_name, ct| {
7484 let decls = emit:: run_state ( false , false , |s| {
7585 rtypes:: emit_toplevel ( s, & kebab_name, ct) ;
7686 host:: emit_toplevel ( s, & kebab_name, ct) ;
@@ -89,11 +99,19 @@ pub fn host_bindgen(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
8999#[ proc_macro]
90100pub fn guest_bindgen ( input : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
91101 let _ = env_logger:: try_init ( ) ;
92- let path: Option < syn:: LitStr > = syn:: parse_macro_input!( input as Option <syn:: LitStr >) ;
93- let path = path
94- . map ( |x| x. value ( ) . into ( ) )
95- . unwrap_or_else ( || std:: env:: var_os ( "WIT_WORLD" ) . unwrap ( ) ) ;
96- util:: read_wit_type_from_file ( path, |kebab_name, ct| {
102+ let parsed_bindgen_input = syn:: parse_macro_input!( input as BindgenInputParams ) ;
103+ let path = parsed_bindgen_input. path . unwrap_or_else ( || {
104+ let wit_world_env = std:: env:: var_os ( "WIT_WORLD" ) ;
105+
106+ if let Some ( env) = wit_world_env {
107+ std:: path:: PathBuf :: from ( env)
108+ } else {
109+ std:: path:: PathBuf :: new ( )
110+ }
111+ } ) ;
112+ let world_name = parsed_bindgen_input. world_name ;
113+
114+ util:: read_wit_type_from_file ( path, world_name, |kebab_name, ct| {
97115 let decls = emit:: run_state ( true , false , |s| {
98116 // Emit type/trait definitions for all instances in the world
99117 rtypes:: emit_toplevel ( s, & kebab_name, ct) ;
@@ -107,3 +125,52 @@ pub fn guest_bindgen(input: proc_macro::TokenStream) -> proc_macro::TokenStream
107125 util:: emit_decls ( decls) . into ( )
108126 } )
109127}
128+
129+ #[ derive( Debug ) ]
130+ struct BindgenInputParams {
131+ world_name : Option < String > ,
132+ path : Option < std:: path:: PathBuf > ,
133+ }
134+
135+ impl Parse for BindgenInputParams {
136+ fn parse ( input : ParseStream ) -> Result < Self > {
137+ let mut path = None ;
138+ let mut world_name = None ;
139+
140+ if input. peek ( syn:: token:: Brace ) {
141+ let content;
142+ syn:: braced!( content in input) ;
143+ eprintln ! ( "Content = \n {:?}" , content) ;
144+
145+ // Parse key-value pairs inside the braces
146+ while !content. is_empty ( ) {
147+ let key: Ident = content. parse ( ) ?;
148+ content. parse :: < Token ! [ : ] > ( ) ?;
149+
150+ match key. to_string ( ) . as_str ( ) {
151+ "world_name" => {
152+ let value: LitStr = content. parse ( ) ?;
153+ world_name = Some ( value. value ( ) ) ;
154+ }
155+ "path" => {
156+ let value: LitStr = content. parse ( ) ?;
157+ path = Some ( std:: path:: PathBuf :: from ( value. value ( ) ) ) ;
158+ }
159+ _ => {
160+ return Err ( syn:: Error :: new ( key. span ( ) , format ! ( "Unknown key: {}" , key) ) ) ;
161+ }
162+ }
163+ // Parse optional comma
164+ if content. peek ( Token ! [ , ] ) {
165+ content. parse :: < Token ! [ , ] > ( ) ?;
166+ }
167+ }
168+ } else {
169+ let option_path_litstr = input. parse :: < Option < syn:: LitStr > > ( ) ?;
170+ if let Some ( concrete_path) = option_path_litstr {
171+ path = Some ( std:: path:: PathBuf :: from ( concrete_path. value ( ) ) ) ;
172+ }
173+ }
174+ Ok ( Self { world_name, path } )
175+ }
176+ }
0 commit comments