@@ -14,8 +14,12 @@ use std::{
14
14
path:: { Path , PathBuf } ,
15
15
} ;
16
16
17
+ pub use ra_cfg:: CfgOptions ;
18
+
17
19
use serde_json:: Value ;
18
20
use text_size:: { TextRange , TextSize } ;
21
+ pub use relative_path:: { RelativePath , RelativePathBuf } ;
22
+ pub use rustc_hash:: FxHashMap ;
19
23
20
24
pub use difference:: Changeset as __Changeset;
21
25
@@ -159,6 +163,33 @@ pub fn add_cursor(text: &str, offset: TextSize) -> String {
159
163
pub struct FixtureEntry {
160
164
pub meta : String ,
161
165
pub text : String ,
166
+
167
+ pub parsed_meta : FixtureMeta ,
168
+ }
169
+
170
+ #[ derive( Debug , Eq , PartialEq ) ]
171
+ pub enum FixtureMeta {
172
+ Root { path : RelativePathBuf } ,
173
+ File ( FileMeta ) ,
174
+ }
175
+
176
+ #[ derive( Debug , Eq , PartialEq ) ]
177
+ pub struct FileMeta {
178
+ pub path : RelativePathBuf ,
179
+ pub krate : Option < String > ,
180
+ pub deps : Vec < String > ,
181
+ pub cfg : ra_cfg:: CfgOptions ,
182
+ pub edition : Option < String > ,
183
+ pub env : FxHashMap < String , String > ,
184
+ }
185
+
186
+ impl FixtureMeta {
187
+ pub fn path ( & self ) -> & RelativePath {
188
+ match self {
189
+ FixtureMeta :: Root { path } => & path,
190
+ FixtureMeta :: File ( f) => & f. path ,
191
+ }
192
+ }
162
193
}
163
194
164
195
/// Parses text which looks like this:
@@ -200,7 +231,8 @@ The offending line: {:?}"#,
200
231
for line in lines. by_ref ( ) {
201
232
if line. starts_with ( "//-" ) {
202
233
let meta = line[ "//-" . len ( ) ..] . trim ( ) . to_string ( ) ;
203
- res. push ( FixtureEntry { meta, text : String :: new ( ) } )
234
+ let parsed_meta = parse_meta ( & meta) ;
235
+ res. push ( FixtureEntry { meta, parsed_meta, text : String :: new ( ) } )
204
236
} else if let Some ( entry) = res. last_mut ( ) {
205
237
entry. text . push_str ( line) ;
206
238
entry. text . push ( '\n' ) ;
@@ -209,6 +241,58 @@ The offending line: {:?}"#,
209
241
res
210
242
}
211
243
244
+ //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo
245
+ fn parse_meta ( meta : & str ) -> FixtureMeta {
246
+ let components = meta. split_ascii_whitespace ( ) . collect :: < Vec < _ > > ( ) ;
247
+
248
+ if components[ 0 ] == "root" {
249
+ let path: RelativePathBuf = components[ 1 ] . into ( ) ;
250
+ assert ! ( path. starts_with( "/" ) && path. ends_with( "/" ) ) ;
251
+ return FixtureMeta :: Root { path } ;
252
+ }
253
+
254
+ let path: RelativePathBuf = components[ 0 ] . into ( ) ;
255
+ assert ! ( path. starts_with( "/" ) ) ;
256
+
257
+ let mut krate = None ;
258
+ let mut deps = Vec :: new ( ) ;
259
+ let mut edition = None ;
260
+ let mut cfg = CfgOptions :: default ( ) ;
261
+ let mut env = FxHashMap :: default ( ) ;
262
+ for component in components[ 1 ..] . iter ( ) {
263
+ let ( key, value) = split1 ( component, ':' ) . unwrap ( ) ;
264
+ match key {
265
+ "crate" => krate = Some ( value. to_string ( ) ) ,
266
+ "deps" => deps = value. split ( ',' ) . map ( |it| it. to_string ( ) ) . collect ( ) ,
267
+ "edition" => edition = Some ( value. to_string ( ) ) ,
268
+ "cfg" => {
269
+ for key in value. split ( ',' ) {
270
+ match split1 ( key, '=' ) {
271
+ None => cfg. insert_atom ( key. into ( ) ) ,
272
+ Some ( ( k, v) ) => cfg. insert_key_value ( k. into ( ) , v. into ( ) ) ,
273
+ }
274
+ }
275
+ }
276
+ "env" => {
277
+ for key in value. split ( ',' ) {
278
+ if let Some ( ( k, v) ) = split1 ( key, '=' ) {
279
+ env. insert ( k. into ( ) , v. into ( ) ) ;
280
+ }
281
+ }
282
+ }
283
+ _ => panic ! ( "bad component: {:?}" , component) ,
284
+ }
285
+ }
286
+
287
+ FixtureMeta :: File ( FileMeta { path, krate, deps, edition, cfg, env } )
288
+ }
289
+
290
+ fn split1 ( haystack : & str , delim : char ) -> Option < ( & str , & str ) > {
291
+ let idx = haystack. find ( delim) ?;
292
+ Some ( ( & haystack[ ..idx] , & haystack[ idx + delim. len_utf8 ( ) ..] ) )
293
+ }
294
+
295
+
212
296
/// Adjusts the indentation of the first line to the minimum indentation of the rest of the lines.
213
297
/// This allows fixtures to start off in a different indentation, e.g. to align the first line with
214
298
/// the other lines visually:
@@ -288,6 +372,18 @@ struct Bar;
288
372
)
289
373
}
290
374
375
+ #[ test]
376
+ fn parse_fixture_gets_full_meta ( ) {
377
+ let fixture = r"
378
+ //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b,atom env:OUTDIR=path/to,OTHER=foo
379
+ " ;
380
+ let parsed = parse_fixture ( fixture) ;
381
+ assert_eq ! ( 1 , parsed. len( ) ) ;
382
+
383
+ let parsed = & parsed[ 0 ] ;
384
+ assert_eq ! ( "\n " , parsed. text) ;
385
+ }
386
+
291
387
/// Same as `parse_fixture`, except it allow empty fixture
292
388
pub fn parse_single_fixture ( fixture : & str ) -> Option < FixtureEntry > {
293
389
if !fixture. lines ( ) . any ( |it| it. trim_start ( ) . starts_with ( "//-" ) ) {
0 commit comments