@@ -163,7 +163,7 @@ impl<E: Diagnostic, C: SourceCode> Diagnostic for WithSourceCode<E, C> {
163
163
}
164
164
165
165
fn source_code ( & self ) -> Option < & dyn miette:: SourceCode > {
166
- Some ( & self . source_code )
166
+ self . error . source_code ( ) . or ( Some ( & self . source_code ) )
167
167
}
168
168
169
169
fn related < ' a > ( & ' a self ) -> Option < Box < dyn Iterator < Item = & ' a dyn Diagnostic > + ' a > > {
@@ -197,7 +197,7 @@ impl<C: SourceCode> Diagnostic for WithSourceCode<Report, C> {
197
197
}
198
198
199
199
fn source_code ( & self ) -> Option < & dyn miette:: SourceCode > {
200
- Some ( & self . source_code )
200
+ self . error . source_code ( ) . or ( Some ( & self . source_code ) )
201
201
}
202
202
203
203
fn related < ' a > ( & ' a self ) -> Option < Box < dyn Iterator < Item = & ' a dyn Diagnostic > + ' a > > {
@@ -232,3 +232,88 @@ impl<C> StdError for WithSourceCode<Report, C> {
232
232
self . error . source ( )
233
233
}
234
234
}
235
+
236
+ #[ cfg( test) ]
237
+ mod tests {
238
+ use thiserror:: Error ;
239
+
240
+ use crate :: { Diagnostic , LabeledSpan , Report , SourceCode , SourceSpan } ;
241
+
242
+ #[ derive( Error , Debug ) ]
243
+ #[ error( "inner" ) ]
244
+ struct Inner {
245
+ pub ( crate ) at : SourceSpan ,
246
+ pub ( crate ) source_code : Option < String > ,
247
+ }
248
+
249
+ impl Diagnostic for Inner {
250
+ fn labels ( & self ) -> Option < Box < dyn Iterator < Item = LabeledSpan > + ' _ > > {
251
+ Some ( Box :: new ( std:: iter:: once ( LabeledSpan :: underline ( self . at ) ) ) )
252
+ }
253
+
254
+ fn source_code ( & self ) -> Option < & dyn SourceCode > {
255
+ self . source_code . as_ref ( ) . map ( |s| s as _ )
256
+ }
257
+ }
258
+
259
+ #[ derive( Error , Debug ) ]
260
+ #[ error( "outer" ) ]
261
+ struct Outer {
262
+ pub ( crate ) errors : Vec < Inner > ,
263
+ }
264
+
265
+ impl Diagnostic for Outer {
266
+ fn related < ' a > ( & ' a self ) -> Option < Box < dyn Iterator < Item = & ' a dyn Diagnostic > + ' a > > {
267
+ Some ( Box :: new ( self . errors . iter ( ) . map ( |e| e as _ ) ) )
268
+ }
269
+ }
270
+
271
+ #[ test]
272
+ fn no_override ( ) {
273
+ let inner_source = "hello world" ;
274
+ let outer_source = "abc" ;
275
+
276
+ let report = Report :: from ( Inner {
277
+ at : ( 0 ..5 ) . into ( ) ,
278
+ source_code : Some ( inner_source. to_string ( ) ) ,
279
+ } )
280
+ . with_source_code ( outer_source. to_string ( ) ) ;
281
+
282
+ let underlined = String :: from_utf8 (
283
+ report
284
+ . source_code ( )
285
+ . unwrap ( )
286
+ . read_span ( & ( 0 ..5 ) . into ( ) , 0 , 0 )
287
+ . unwrap ( )
288
+ . data ( )
289
+ . to_vec ( ) ,
290
+ )
291
+ . unwrap ( ) ;
292
+ assert_eq ! ( underlined, "hello" ) ;
293
+ }
294
+
295
+ #[ test]
296
+ #[ cfg( feature = "fancy" ) ]
297
+ fn two_source_codes ( ) {
298
+ let inner_source = "hello world" ;
299
+ let outer_source = "abc" ;
300
+
301
+ let report = Report :: from ( Outer {
302
+ errors : vec ! [
303
+ Inner {
304
+ at: ( 0 ..5 ) . into( ) ,
305
+ source_code: Some ( inner_source. to_string( ) ) ,
306
+ } ,
307
+ Inner {
308
+ at: ( 1 ..2 ) . into( ) ,
309
+ source_code: None ,
310
+ } ,
311
+ ] ,
312
+ } )
313
+ . with_source_code ( outer_source. to_string ( ) ) ;
314
+
315
+ let message = format ! ( "{:?}" , report) ;
316
+ assert ! ( message. contains( inner_source) ) ;
317
+ assert ! ( message. contains( outer_source) ) ;
318
+ }
319
+ }
0 commit comments