@@ -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
@@ -63,14 +65,23 @@ use hyperlight_component_util::*;
6365/// `instantiate()` method on the component trait that makes
6466/// instantiating the sandbox particularly ergonomic in core
6567/// Hyperlight.
68+
6669#[ proc_macro]
6770pub fn host_bindgen ( input : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
6871 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| {
72+ let parsed_bindgen_input = syn:: parse_macro_input!( input as BindgenInputParams ) ;
73+ let path = parsed_bindgen_input. path . unwrap_or_else ( || {
74+ let wit_world_env = std:: env:: var_os ( "WIT_WORLD" ) ;
75+
76+ if let Some ( env) = wit_world_env {
77+ std:: path:: PathBuf :: from ( env)
78+ } else {
79+ std:: path:: PathBuf :: new ( )
80+ }
81+ } ) ;
82+ let world_name = parsed_bindgen_input. world_name ;
83+
84+ util:: read_wit_type_from_file ( path, world_name, |kebab_name, ct| {
7485 let decls = emit:: run_state ( false , false , |s| {
7586 rtypes:: emit_toplevel ( s, & kebab_name, ct) ;
7687 host:: emit_toplevel ( s, & kebab_name, ct) ;
@@ -89,11 +100,19 @@ pub fn host_bindgen(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
89100#[ proc_macro]
90101pub fn guest_bindgen ( input : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
91102 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| {
103+ let parsed_bindgen_input = syn:: parse_macro_input!( input as BindgenInputParams ) ;
104+ let path = parsed_bindgen_input. path . unwrap_or_else ( || {
105+ let wit_world_env = std:: env:: var_os ( "WIT_WORLD" ) ;
106+
107+ if let Some ( env) = wit_world_env {
108+ std:: path:: PathBuf :: from ( env)
109+ } else {
110+ std:: path:: PathBuf :: new ( )
111+ }
112+ } ) ;
113+ let world_name = parsed_bindgen_input. world_name ;
114+
115+ util:: read_wit_type_from_file ( path, world_name, |kebab_name, ct| {
97116 let decls = emit:: run_state ( true , false , |s| {
98117 // Emit type/trait definitions for all instances in the world
99118 rtypes:: emit_toplevel ( s, & kebab_name, ct) ;
@@ -107,3 +126,52 @@ pub fn guest_bindgen(input: proc_macro::TokenStream) -> proc_macro::TokenStream
107126 util:: emit_decls ( decls) . into ( )
108127 } )
109128}
129+
130+ #[ derive( Debug ) ]
131+ struct BindgenInputParams {
132+ world_name : Option < String > ,
133+ path : Option < std:: path:: PathBuf > ,
134+ }
135+
136+ impl Parse for BindgenInputParams {
137+ fn parse ( input : ParseStream ) -> Result < Self > {
138+ let mut path = None ;
139+ let mut world_name = None ;
140+
141+ if input. peek ( syn:: token:: Brace ) {
142+ let content;
143+ syn:: braced!( content in input) ;
144+ eprintln ! ( "Content = \n {:?}" , content) ;
145+
146+ // Parse key-value pairs inside the braces
147+ while !content. is_empty ( ) {
148+ let key: Ident = content. parse ( ) ?;
149+ content. parse :: < Token ! [ : ] > ( ) ?;
150+
151+ match key. to_string ( ) . as_str ( ) {
152+ "world_name" => {
153+ let value: LitStr = content. parse ( ) ?;
154+ world_name = Some ( value. value ( ) ) ;
155+ }
156+ "path" => {
157+ let value: LitStr = content. parse ( ) ?;
158+ path = Some ( std:: path:: PathBuf :: from ( value. value ( ) ) ) ;
159+ }
160+ _ => {
161+ return Err ( syn:: Error :: new ( key. span ( ) , format ! ( "Unknown key: {}" , key) ) ) ;
162+ }
163+ }
164+ // Parse optional comma
165+ if content. peek ( Token ! [ , ] ) {
166+ content. parse :: < Token ! [ , ] > ( ) ?;
167+ }
168+ }
169+ } else {
170+ let option_path_litstr = input. parse :: < Option < syn:: LitStr > > ( ) ?;
171+ if let Some ( concrete_path) = option_path_litstr {
172+ path = Some ( std:: path:: PathBuf :: from ( concrete_path. value ( ) ) ) ;
173+ }
174+ }
175+ Ok ( Self { world_name, path } )
176+ }
177+ }
0 commit comments