@@ -5,7 +5,8 @@ use std::path::{Path, PathBuf};
5
5
use std:: sync:: atomic:: { AtomicUsize , Ordering :: Relaxed } ;
6
6
use syn:: parse:: { Error , Parse , ParseStream , Result } ;
7
7
use syn:: punctuated:: Punctuated ;
8
- use syn:: { braced, token, Token } ;
8
+ use syn:: spanned:: Spanned ;
9
+ use syn:: { braced, token, LitStr , Token } ;
9
10
use wit_bindgen_core:: wit_parser:: { PackageId , Resolve , UnresolvedPackageGroup , WorldId } ;
10
11
use wit_bindgen_rust:: { Opts , Ownership , WithOption } ;
11
12
@@ -50,9 +51,9 @@ struct Config {
50
51
/// The source of the wit package definition
51
52
enum Source {
52
53
/// A path to a wit directory
53
- Path ( String ) ,
54
+ Paths ( Vec < PathBuf > ) ,
54
55
/// Inline sources have an optional path to a directory of their dependencies
55
- Inline ( String , Option < PathBuf > ) ,
56
+ Inline ( String , Option < Vec < PathBuf > > ) ,
56
57
}
57
58
58
59
impl Parse for Config {
@@ -69,15 +70,15 @@ impl Parse for Config {
69
70
let fields = Punctuated :: < Opt , Token ! [ , ] > :: parse_terminated ( & content) ?;
70
71
for field in fields. into_pairs ( ) {
71
72
match field. into_value ( ) {
72
- Opt :: Path ( s) => {
73
+ Opt :: Path ( span, p) => {
74
+ let paths = p. into_iter ( ) . map ( |f| PathBuf :: from ( f. value ( ) ) ) . collect ( ) ;
75
+
73
76
source = Some ( match source {
74
- Some ( Source :: Path ( _) ) | Some ( Source :: Inline ( _, Some ( _) ) ) => {
75
- return Err ( Error :: new ( s . span ( ) , "cannot specify second source" ) ) ;
77
+ Some ( Source :: Paths ( _) ) | Some ( Source :: Inline ( _, Some ( _) ) ) => {
78
+ return Err ( Error :: new ( span, "cannot specify second source" ) ) ;
76
79
}
77
- Some ( Source :: Inline ( i, None ) ) => {
78
- Source :: Inline ( i, Some ( PathBuf :: from ( s. value ( ) ) ) )
79
- }
80
- None => Source :: Path ( s. value ( ) ) ,
80
+ Some ( Source :: Inline ( i, None ) ) => Source :: Inline ( i, Some ( paths) ) ,
81
+ None => Source :: Paths ( paths) ,
81
82
} )
82
83
}
83
84
Opt :: World ( s) => {
@@ -91,9 +92,7 @@ impl Parse for Config {
91
92
Some ( Source :: Inline ( _, _) ) => {
92
93
return Err ( Error :: new ( s. span ( ) , "cannot specify second source" ) ) ;
93
94
}
94
- Some ( Source :: Path ( p) ) => {
95
- Source :: Inline ( s. value ( ) , Some ( PathBuf :: from ( p) ) )
96
- }
95
+ Some ( Source :: Paths ( p) ) => Source :: Inline ( s. value ( ) , Some ( p) ) ,
97
96
None => Source :: Inline ( s. value ( ) , None ) ,
98
97
} )
99
98
}
@@ -143,7 +142,9 @@ impl Parse for Config {
143
142
} else {
144
143
world = input. parse :: < Option < syn:: LitStr > > ( ) ?. map ( |s| s. value ( ) ) ;
145
144
if input. parse :: < Option < syn:: token:: In > > ( ) ?. is_some ( ) {
146
- source = Some ( Source :: Path ( input. parse :: < syn:: LitStr > ( ) ?. value ( ) ) ) ;
145
+ source = Some ( Source :: Paths ( vec ! [ PathBuf :: from(
146
+ input. parse:: <syn:: LitStr >( ) ?. value( ) ,
147
+ ) ] ) ) ;
147
148
}
148
149
}
149
150
let ( resolve, pkgs, files) =
@@ -168,31 +169,36 @@ fn parse_source(
168
169
let mut resolve = Resolve :: default ( ) ;
169
170
resolve. features . extend ( features. iter ( ) . cloned ( ) ) ;
170
171
let mut files = Vec :: new ( ) ;
172
+ let mut pkgs = Vec :: new ( ) ;
171
173
let root = PathBuf :: from ( std:: env:: var ( "CARGO_MANIFEST_DIR" ) . unwrap ( ) ) ;
172
- let mut parse = |path : & Path | -> anyhow:: Result < _ > {
173
- // Try to normalize the path to make the error message more understandable when
174
- // the path is not correct. Fallback to the original path if normalization fails
175
- // (probably return an error somewhere else).
176
- let normalized_path = match std:: fs:: canonicalize ( path) {
177
- Ok ( p) => p,
178
- Err ( _) => path. to_path_buf ( ) ,
179
- } ;
180
- let ( pkg, sources) = resolve. push_path ( normalized_path) ?;
181
- files. extend ( sources) ;
182
- Ok ( pkg)
174
+ let mut parse = |paths : & [ PathBuf ] | -> anyhow:: Result < ( ) > {
175
+ for path in paths {
176
+ let p = root. join ( path) ;
177
+ // Try to normalize the path to make the error message more understandable when
178
+ // the path is not correct. Fallback to the original path if normalization fails
179
+ // (probably return an error somewhere else).
180
+ let normalized_path = match std:: fs:: canonicalize ( & p) {
181
+ Ok ( p) => p,
182
+ Err ( _) => p. to_path_buf ( ) ,
183
+ } ;
184
+ let ( pkg, sources) = resolve. push_path ( normalized_path) ?;
185
+ pkgs. extend ( pkg) ;
186
+ files. extend ( sources) ;
187
+ }
188
+ Ok ( ( ) )
183
189
} ;
184
- let pkg = match source {
190
+ match source {
185
191
Some ( Source :: Inline ( s, path) ) => {
186
192
if let Some ( p) = path {
187
- parse ( & root . join ( p ) ) ?;
193
+ parse ( p ) ?;
188
194
}
189
- resolve. push_group ( UnresolvedPackageGroup :: parse ( "macro-input" , s) ?) ?
195
+ pkgs = resolve. push_group ( UnresolvedPackageGroup :: parse ( "macro-input" , s) ?) ?;
190
196
}
191
- Some ( Source :: Path ( s ) ) => parse ( & root . join ( s ) ) ?,
192
- None => parse ( & root. join ( "wit" ) ) ?,
197
+ Some ( Source :: Paths ( p ) ) => parse ( p ) ?,
198
+ None => parse ( & vec ! [ root. join( "wit" ) ] ) ?,
193
199
} ;
194
200
195
- Ok ( ( resolve, pkg , files) )
201
+ Ok ( ( resolve, pkgs , files) )
196
202
}
197
203
198
204
impl Config {
@@ -298,7 +304,7 @@ impl From<ExportKey> for wit_bindgen_rust::ExportKey {
298
304
299
305
enum Opt {
300
306
World ( syn:: LitStr ) ,
301
- Path ( syn:: LitStr ) ,
307
+ Path ( Span , Vec < syn:: LitStr > ) ,
302
308
Inline ( syn:: LitStr ) ,
303
309
UseStdFeature ,
304
310
RawStrings ,
@@ -327,7 +333,18 @@ impl Parse for Opt {
327
333
if l. peek ( kw:: path) {
328
334
input. parse :: < kw:: path > ( ) ?;
329
335
input. parse :: < Token ! [ : ] > ( ) ?;
330
- Ok ( Opt :: Path ( input. parse ( ) ?) )
336
+ // the `path` supports two forms:
337
+ // * path: "xxx"
338
+ // * path: ["aaa", "bbb"]
339
+ if input. peek ( token:: Bracket ) {
340
+ let contents;
341
+ syn:: bracketed!( contents in input) ;
342
+ let list = Punctuated :: < _ , Token ! [ , ] > :: parse_terminated ( & contents) ?;
343
+ Ok ( Opt :: Path ( list. span ( ) , list. into_iter ( ) . collect ( ) ) )
344
+ } else {
345
+ let path: LitStr = input. parse ( ) ?;
346
+ Ok ( Opt :: Path ( path. span ( ) , vec ! [ path] ) )
347
+ }
331
348
} else if l. peek ( kw:: inline) {
332
349
input. parse :: < kw:: inline > ( ) ?;
333
350
input. parse :: < Token ! [ : ] > ( ) ?;
0 commit comments