@@ -109,6 +109,14 @@ struct Cpp {
109109 import_prefix : Option < String > ,
110110}
111111
112+ #[ cfg( feature = "clap" ) ]
113+ fn parse_with ( s : & str ) -> Result < ( String , String ) , String > {
114+ let ( k, v) = s. split_once ( '=' ) . ok_or_else ( || {
115+ format ! ( "expected string of form `<key>=<value>[,<key>=<value>...]`; got `{s}`" )
116+ } ) ?;
117+ Ok ( ( k. to_string ( ) , v. to_string ( ) ) )
118+ }
119+
112120#[ derive( Default , Debug , Clone ) ]
113121#[ cfg_attr( feature = "clap" , derive( clap:: Args ) ) ]
114122pub struct Opts {
@@ -165,6 +173,14 @@ pub struct Opts {
165173 /// Where to place output files
166174 #[ cfg_attr( feature = "clap" , arg( skip) ) ]
167175 out_dir : Option < PathBuf > ,
176+
177+ /// Importing wit interface from custom include
178+ ///
179+ /// Argument must be of the form `k=v` and this option can be passed
180+ /// multiple times or one option can be comma separated, for example
181+ /// `k1=v1,k2=v2`.
182+ #[ cfg_attr( feature = "clap" , arg( long, value_parser = parse_with, value_delimiter = ',' ) ) ]
183+ pub with : Vec < ( String , String ) > ,
168184}
169185
170186/// Supported API styles for the generated bindings.
@@ -498,29 +514,46 @@ impl WorldGenerator for Cpp {
498514 id : InterfaceId ,
499515 _files : & mut Files ,
500516 ) -> anyhow:: Result < ( ) > {
501- if let Some ( prefix) = self
502- . interface_prefixes
503- . get ( & ( Direction :: Import , name. clone ( ) ) )
504- {
505- self . import_prefix = Some ( prefix. clone ( ) ) ;
506- }
507-
508- let store = self . start_new_file ( None ) ;
509517 self . imported_interfaces . insert ( id) ;
510- let wasm_import_module = resolve. name_world_key ( name) ;
511- let binding = Some ( name) ;
512- let mut r#gen = self . interface ( resolve, binding, true , Some ( wasm_import_module) ) ;
513- r#gen. interface = Some ( id) ;
514- r#gen. types ( id) ;
515- let namespace = namespace ( resolve, & TypeOwner :: Interface ( id) , false , & r#gen. r#gen . opts ) ;
516518
517- for ( _name, func) in resolve. interfaces [ id] . functions . iter ( ) {
518- if matches ! ( func. kind, FunctionKind :: Freestanding ) {
519- r#gen. r#gen . h_src . change_namespace ( & namespace) ;
520- r#gen. generate_function ( func, & TypeOwner :: Interface ( id) , AbiVariant :: GuestImport ) ;
519+ let full_name = resolve. name_world_key ( name) ;
520+ match self . opts . with . iter ( ) . find ( |e| e. 0 == full_name) {
521+ None => {
522+ if let Some ( prefix) = self
523+ . interface_prefixes
524+ . get ( & ( Direction :: Import , name. clone ( ) ) )
525+ {
526+ self . import_prefix = Some ( prefix. clone ( ) ) ;
527+ }
528+
529+ let store = self . start_new_file ( None ) ;
530+ let wasm_import_module = resolve. name_world_key ( name) ;
531+ let binding = Some ( name) ;
532+ let mut r#gen = self . interface ( resolve, binding, true , Some ( wasm_import_module) ) ;
533+ r#gen. interface = Some ( id) ;
534+ r#gen. types ( id) ;
535+ let namespace =
536+ namespace ( resolve, & TypeOwner :: Interface ( id) , false , & r#gen. r#gen . opts ) ;
537+
538+ for ( _name, func) in resolve. interfaces [ id] . functions . iter ( ) {
539+ if matches ! ( func. kind, FunctionKind :: Freestanding ) {
540+ r#gen. r#gen . h_src . change_namespace ( & namespace) ;
541+ r#gen. generate_function (
542+ func,
543+ & TypeOwner :: Interface ( id) ,
544+ AbiVariant :: GuestImport ,
545+ ) ;
546+ }
547+ }
548+ self . finish_file ( & namespace, store) ;
549+ }
550+ Some ( ( _, val) ) => {
551+ let with_quotes = format ! ( "\" {val}\" " ) ;
552+ if !self . includes . contains ( & with_quotes) {
553+ self . includes . push ( with_quotes) ;
554+ }
521555 }
522556 }
523- self . finish_file ( & namespace, store) ;
524557 let _ = self . import_prefix . take ( ) ;
525558 Ok ( ( ) )
526559 }
0 commit comments