203
203
//! Empty braces can be omitted as of quick_error 0.1.3.
204
204
//!
205
205
206
+
206
207
/// Main macro that does all the work
207
208
#[ macro_export]
208
209
macro_rules! quick_error {
209
210
( $( #[ $meta: meta] ) *
210
211
pub enum $name: ident { $( $chunks: tt) * }
211
212
) => {
212
213
quick_error!( SORT [ pub enum $name $( #[ $meta] ) * ]
213
- enum [ ] items [ ] buf [ ]
214
+ items [ ] buf [ ]
214
215
queue [ $( $chunks) * ] ) ;
215
216
} ;
216
217
( $( #[ $meta: meta] ) *
217
218
enum $name: ident { $( $chunks: tt) * }
218
219
) => {
219
220
quick_error!( SORT [ enum $name $( #[ $meta] ) * ]
220
- enum [ ] items [ ] buf [ ]
221
+ items [ ] buf [ ]
221
222
queue [ $( $chunks) * ] ) ;
222
223
} ;
223
224
// Queue is empty, can do the work
224
225
( SORT [ enum $name: ident $( #[ $meta: meta] ) * ]
225
- enum [ $( $( #[ $emeta: meta] ) *
226
- => $eitem: ident $( ( $( $etyp: ty) ,* ) ) * ) * ]
227
- items [ $( $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
226
+ items [ $( $( #[ $imeta: imeta] ) *
227
+ => $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
228
228
{ $( $ifuncs: tt) * } ) * ]
229
229
buf [ ]
230
230
queue [ ]
231
231
) => {
232
232
$( #[ $meta] ) *
233
233
enum $name {
234
234
$(
235
- $( #[ $emeta ] ) *
236
- $eitem $( ( $( $etyp ) ,* ) ) * ,
235
+ $( #[ $imeta ] ) *
236
+ $iitem $( ( $( $ityp ) ,* ) ) * ,
237
237
) *
238
238
}
239
239
quick_error!( IMPLEMENTATIONS $name { $(
@@ -244,18 +244,17 @@ macro_rules! quick_error {
244
244
) *
245
245
} ;
246
246
( SORT [ pub enum $name: ident $( #[ $meta: meta] ) * ]
247
- enum [ $( $( #[ $emeta: meta] ) *
248
- => $eitem: ident $( ( $( $etyp: ty) ,* ) ) * ) * ]
249
- items [ $( $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
247
+ items [ $( $( #[ $imeta: meta] ) *
248
+ => $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
250
249
{ $( $ifuncs: tt) * } ) * ]
251
250
buf [ ]
252
251
queue [ ]
253
252
) => {
254
253
$( #[ $meta] ) *
255
254
pub enum $name {
256
255
$(
257
- $( #[ $emeta ] ) *
258
- $eitem $( ( $( $etyp ) ,* ) ) * ,
256
+ $( #[ $imeta ] ) *
257
+ $iitem $( ( $( $ityp ) ,* ) ) * ,
259
258
) *
260
259
}
261
260
quick_error!( IMPLEMENTATIONS $name { $(
@@ -267,39 +266,35 @@ macro_rules! quick_error {
267
266
} ;
268
267
// Add meta to buffer
269
268
( SORT [ $( $def: tt) * ]
270
- enum [ $( $( #[ $emeta: meta] ) *
271
- => $eitem: ident $( ( $( $etyp: ty) ,* ) ) * ) * ]
272
- items [ $( $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
269
+ items [ $( $( #[ $imeta: meta] ) *
270
+ => $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
273
271
{ $( $ifuncs: tt) * } ) * ]
274
272
buf [ $( #[ $bmeta: meta] ) * ]
275
273
queue [ #[ $qmeta: meta] $( $tail: tt) * ]
276
274
) => {
277
275
quick_error!( SORT [ $( $def) * ]
278
- enum [ $( $( #[ $emeta] ) * => $eitem $( ( $( $etyp) ,* ) ) * ) * ]
279
- items [ $( $iitem $( ( $( $ivar: $ityp) ,* ) ) * { $( $ifuncs) * } ) * ]
276
+ items [ $( $( #[ $imeta] ) * => $iitem $( ( $( $ivar: $ityp) ,* ) ) * { $( $ifuncs) * } ) * ]
280
277
buf [ $( #[ $bmeta] ) * #[ $qmeta] ]
281
278
queue [ $( $tail) * ] ) ;
282
279
} ;
283
280
// Add ident to buffer
284
281
( SORT [ $( $def: tt) * ]
285
- enum [ $( $( #[ $emeta: meta] ) *
286
- => $eitem: ident $( ( $( $etyp: ty) ,* ) ) * ) * ]
287
- items [ $( $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
282
+ items [ $( $( #[ $imeta: meta] ) *
283
+ => $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
288
284
{ $( $ifuncs: tt) * } ) * ]
289
285
buf [ $( #[ $bmeta: meta] ) * ]
290
286
queue [ $qitem: ident $( $tail: tt) * ]
291
287
) => {
292
288
quick_error!( SORT [ $( $def) * ]
293
- enum [ $( $( #[ $emeta ] ) * => $eitem $ ( ( $ ( $etyp ) , * ) ) * ) * ]
294
- items [ $ ( $iitem $( ( $( $ivar: $ityp) ,* ) ) * { $( $ifuncs) * } ) * ]
289
+ items [ $( $( #[ $imeta ] ) *
290
+ => $iitem $( ( $( $ivar: $ityp) ,* ) ) * { $( $ifuncs) * } ) * ]
295
291
buf [ $( #[ $bmeta] ) * => $qitem ]
296
292
queue [ $( $tail) * ] ) ;
297
293
} ;
298
294
// Flush buffer on meta after ident
299
295
( SORT [ $( $def: tt) * ]
300
- enum [ $( $( #[ $emeta: meta] ) *
301
- => $eitem: ident $( ( $( $etyp: ty) ,* ) ) * ) * ]
302
- items [ $( $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
296
+ items [ $( $( #[ $imeta: meta] ) *
297
+ => $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
303
298
{ $( $ifuncs: tt) * } ) * ]
304
299
buf [ $( #[ $bmeta: meta] ) *
305
300
=> $bitem: ident $( ( $( $bvar: ident : $btyp: ty) ,* ) ) * ]
@@ -308,77 +303,67 @@ macro_rules! quick_error {
308
303
quick_error!( SORT [ $( $def) * ]
309
304
enum [ $( $( #[ $emeta] ) * => $eitem $( ( $( $etyp) ,* ) ) * ) *
310
305
$( #[ $bmeta] ) * => $bitem $( ( $( $btyp) ,* ) ) * ]
311
- items [ $( $iitem $( ( $( $ivar: $ityp) ,* ) ) * { $( $ifuncs) * } ) *
306
+ items [ $( $( #[ $imeta: imeta] ) *
307
+ => $iitem $( ( $( $ivar: $ityp) ,* ) ) * { $( $ifuncs) * } ) *
312
308
$bitem $( ( $( $bvar: $btyp) ,* ) ) * { } ]
313
309
buf [ #[ $qmeta] ]
314
310
queue [ $( $tail) * ] ) ;
315
311
} ;
316
312
// Add parenthesis
317
313
( SORT [ $( $def: tt) * ]
318
- enum [ $( $( #[ $emeta: meta] ) *
319
- => $eitem: ident $( ( $( $etyp: ty) ,* ) ) * ) * ]
320
- items [ $( $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
314
+ items [ $( $( #[ $imeta: meta] ) *
315
+ => $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
321
316
{ $( $ifuncs: tt) * } ) * ]
322
317
buf [ $( #[ $bmeta: meta] ) * => $bitem: ident ]
323
318
queue [ ( $( $qvar: ident : $qtyp: ty ) ,* ) $( $tail: tt) * ]
324
319
) => {
325
320
quick_error!( SORT [ $( $def) * ]
326
- enum [ $( $( #[ $emeta] ) * => $eitem $( ( $( $etyp) ,* ) ) * ) * ]
327
- items [ $( $iitem $( ( $( $ivar: $ityp) ,* ) ) * { $( $ifuncs) * } ) * ]
321
+ items [ $( $( #[ $imeta] ) * => $iitem $( ( $( $ivar: $ityp) ,* ) ) * { $( $ifuncs) * } ) * ]
328
322
buf [ $( #[ $bmeta] ) * => $bitem ( $( $qvar: $qtyp ) ,* ) ]
329
323
queue [ $( $tail) * ] ) ;
330
324
} ;
331
325
// Add braces and flush always on braces
332
326
( SORT [ $( $def: tt) * ]
333
- enum [ $( $( #[ $emeta: meta] ) *
334
- => $eitem: ident $( ( $( $etyp: ty) ,* ) ) * ) * ]
335
- items [ $( $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
327
+ items [ $( $( #[ $imeta: meta] ) *
328
+ => $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
336
329
{ $( $ifuncs: tt) * } ) * ]
337
330
buf [ $( #[ $bmeta: meta] ) *
338
331
=> $bitem: ident $( ( $( $bvar: ident : $btyp: ty) ,* ) ) * ]
339
332
queue [ { $( $qfuncs: tt) * } $( $tail: tt) * ]
340
333
) => {
341
334
quick_error!( SORT [ $( $def) * ]
342
- enum [ $( $( #[ $emeta] ) * => $eitem $( ( $( $etyp) ,* ) ) * ) *
343
- $( #[ $bmeta] ) * => $bitem $( ( $( $btyp) ,* ) ) * ]
344
- items [ $( $iitem $( ( $( $ivar: $ityp) ,* ) ) * { $( $ifuncs) * } ) *
345
- $bitem $( ( $( $bvar: $btyp) ,* ) ) * { $( $qfuncs) * } ]
335
+ items [ $( $( #[ $imeta] ) * => $iitem $( ( $( $ivar: $ityp) ,* ) ) * { $( $ifuncs) * } ) *
336
+ $( #[ $bmeta] ) * => $bitem $( ( $( $bvar: $btyp) ,* ) ) * { $( $qfuncs) * } ]
346
337
buf [ ]
347
338
queue [ $( $tail) * ] ) ;
348
339
} ;
349
340
// Flush buffer on double ident
350
341
( SORT [ $( $def: tt) * ]
351
- enum [ $( $( #[ $emeta: meta] ) *
352
- => $eitem: ident $( ( $( $etyp: ty) ,* ) ) * ) * ]
353
- items [ $( $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
342
+ items [ $( $( #[ $imeta: meta] ) *
343
+ => $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
354
344
{ $( $ifuncs: tt) * } ) * ]
355
345
buf [ $( #[ $bmeta: meta] ) *
356
346
=> $bitem: ident $( ( $( $bvar: ident : $btyp: ty) ,* ) ) * ]
357
347
queue [ $qitem: ident $( $tail: tt) * ]
358
348
) => {
359
349
quick_error!( SORT [ $( $def) * ]
360
- enum [ $( $( #[ $emeta] ) * => $eitem $( ( $( $etyp) ,* ) ) * ) *
361
- $( #[ $bmeta] ) * => $bitem $( ( $( $btyp) ,* ) ) * ]
362
- items [ $( $iitem $( ( $( $ivar: $ityp) ,* ) ) * { $( $ifuncs) * } ) *
363
- $bitem $( ( $( $bvar: $btyp) ,* ) ) * { } ]
350
+ items [ $( $( #[ $imeta] ) * => $iitem $( ( $( $ivar: $ityp) ,* ) ) * { $( $ifuncs) * } ) *
351
+ $( #[ $bmeta] ) * => $bitem $( ( $( $bvar: $btyp) ,* ) ) * { } ]
364
352
buf [ => $qitem ]
365
353
queue [ $( $tail) * ] ) ;
366
354
} ;
367
355
// Flush buffer on end
368
356
( SORT [ $( $def: tt) * ]
369
- enum [ $( $( #[ $emeta: meta] ) *
370
- => $eitem: ident $( ( $( $etyp: ty) ,* ) ) * ) * ]
371
- items [ $( $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
357
+ items [ $( $( #[ $imeta: meta] ) *
358
+ => $iitem: ident $( ( $( $ivar: ident : $ityp: ty) ,* ) ) *
372
359
{ $( $ifuncs: tt) * } ) * ]
373
360
buf [ $( #[ $bmeta: meta] ) *
374
361
=> $bitem: ident $( ( $( $bvar: ident : $btyp: ty) ,* ) ) * ]
375
362
queue [ ]
376
363
) => {
377
364
quick_error!( SORT [ $( $def) * ]
378
- enum [ $( $( #[ $emeta] ) * => $eitem $( ( $( $etyp) ,* ) ) * ) *
379
- $( #[ $bmeta] ) * => $bitem $( ( $( $btyp) ,* ) ) * ]
380
- items [ $( $iitem $( ( $( $ivar: $ityp) ,* ) ) * { $( $ifuncs) * } ) *
381
- $bitem $( ( $( $bvar: $btyp) ,* ) ) * { } ]
365
+ items [ $( $( #[ $imeta] ) * => $iitem $( ( $( $ivar: $ityp) ,* ) ) * { $( $ifuncs) * } ) *
366
+ $( #[ $bmeta] ) * => $bitem $( ( $( $bvar: $btyp) ,* ) ) * { } ]
382
367
buf [ ]
383
368
queue [ ] ) ;
384
369
} ;
@@ -588,7 +573,9 @@ macro_rules! quick_error {
588
573
589
574
#[ cfg( test) ]
590
575
mod test {
591
- use std:: io;
576
+ use std:: num:: ParseFloatError ;
577
+ use std:: str:: Utf8Error ;
578
+ use std:: string:: FromUtf8Error ;
592
579
use std:: error:: Error ;
593
580
594
581
quick_error ! {
@@ -616,26 +603,25 @@ mod test {
616
603
}
617
604
618
605
quick_error ! {
619
- #[ derive( Debug ) ]
620
- pub enum IoWrapper {
621
- /// I/O Error
622
- Io ( err: io :: Error ) {
606
+ #[ derive( Debug , PartialEq ) ]
607
+ pub enum Wrapper {
608
+ /// ParseFloat Error
609
+ ParseFloatError ( err: ParseFloatError ) {
623
610
from( )
624
611
description( err. description( ) )
625
- display( "I/O error: {err}" , err=err)
612
+ display( "parse float error: {err}" , err=err)
626
613
cause( err)
627
614
}
628
615
Other ( descr: & ' static str ) {
629
616
description( descr)
630
617
display( "Error: {}" , descr)
631
618
}
632
- /// I/O error with some context
633
- IoAt ( place : & ' static str , err : io :: Error ) {
619
+ /// FromUtf8 Error
620
+ FromUtf8Error ( err : Utf8Error , source : Vec < u8 > ) {
634
621
cause( err)
635
- display( self_) -> ( "{} {}: {}" , self_. description( ) , place, err)
636
- description( "io error at" )
637
- from( s: String ) -> ( "idea" ,
638
- io:: Error :: new( io:: ErrorKind :: Other , s) )
622
+ display( me) -> ( "{desc} at index {pos}: {err}" , desc=me. description( ) , pos=err. valid_up_to( ) , err=err)
623
+ description( "utf8 error" )
624
+ from( err: FromUtf8Error ) -> ( err. utf8_error( ) . clone( ) , err. into_bytes( ) )
639
625
}
640
626
Discard {
641
627
from( & ' static str )
@@ -647,72 +633,68 @@ mod test {
647
633
}
648
634
649
635
#[ test]
650
- fn io_wrapper_err ( ) {
651
- let io1 = IoWrapper :: Io (
652
- io:: Error :: new ( io:: ErrorKind :: Other , "some error" ) ) ;
653
- assert_eq ! ( format!( "{}" , io1) , "I/O error: some error" . to_string( ) ) ;
654
- assert_eq ! ( format!( "{:?}" , io1) ,
655
- "Io(Error { repr: Custom(Custom { kind: Other, \
656
- error: StringError(\" some error\" ) }) })". to_string( ) ) ;
657
- assert_eq ! ( io1. description( ) , "some error" ) ;
658
- assert_eq ! ( io1. cause( ) . unwrap( ) . description( ) , "some error" ) ;
636
+ fn wrapper_err ( ) {
637
+ let cause = "one and a half times pi" . parse :: < f32 > ( ) . unwrap_err ( ) ;
638
+ let err = Wrapper :: ParseFloatError ( cause. clone ( ) ) ;
639
+ assert_eq ! ( format!( "{}" , err) , format!( "parse float error: {}" , cause) ) ;
640
+ assert_eq ! ( format!( "{:?}" , err) , format!( "ParseFloatError({:?})" , cause) ) ;
641
+ assert_eq ! ( err. description( ) , cause. description( ) ) ;
642
+ assert_eq ! ( format!( "{:?}" , err. cause( ) . unwrap( ) ) , format!( "{:?}" , cause) ) ;
659
643
}
660
644
661
645
#[ test]
662
- fn io_wrapper_trait_str ( ) {
663
- let err: & Error = & IoWrapper :: Other ( "hello" ) ;
664
- assert_eq ! ( format!( "{}" , err) , "Error: hello" . to_string( ) ) ;
665
- assert_eq ! ( format!( "{:?}" , err) , "Other(\" hello\" )" . to_string( ) ) ;
666
- assert_eq ! ( err. description( ) , "hello" . to_string( ) ) ;
646
+ fn wrapper_trait_str ( ) {
647
+ let desc = "hello" ;
648
+ let err: & Error = & Wrapper :: Other ( desc) ;
649
+ assert_eq ! ( format!( "{}" , err) , format!( "Error: {}" , desc) ) ;
650
+ assert_eq ! ( format!( "{:?}" , err) , format!( "Other({:?})" , desc) ) ;
651
+ assert_eq ! ( err. description( ) , desc) ;
667
652
assert ! ( err. cause( ) . is_none( ) ) ;
668
653
}
669
654
670
655
#[ test]
671
- fn io_wrapper_trait_two_fields ( ) {
672
- let io1 = IoWrapper :: Io (
673
- io:: Error :: new ( io:: ErrorKind :: Other , "some error" ) ) ;
674
- let err: & Error = & IoWrapper :: IoAt ( "file" ,
675
- io:: Error :: new ( io:: ErrorKind :: NotFound , io1) ) ;
676
- assert_eq ! ( format!( "{}" , err) ,
677
- "io error at file: I/O error: some error" . to_string( ) ) ;
678
- assert_eq ! ( format!( "{:?}" , err) , "IoAt(\" file\" , Error { \
679
- repr: Custom(Custom { kind: NotFound, \
680
- error: Io(Error { repr: Custom(Custom { \
681
- kind: Other, error: StringError(\" some error\" ) \
682
- }) }) }) })". to_string( ) ) ;
683
- assert_eq ! ( err. description( ) , "io error at" ) ;
684
- assert_eq ! ( err. cause( ) . unwrap( ) . description( ) , "some error" ) ;
656
+ fn wrapper_trait_two_fields ( ) {
657
+ let invalid_utf8: Vec < u8 > = vec ! [ 0 , 159 , 146 , 150 ] ;
658
+ let cause = String :: from_utf8 ( invalid_utf8. clone ( ) ) . unwrap_err ( ) . utf8_error ( ) ;
659
+ let err: & Error = & Wrapper :: FromUtf8Error ( cause. clone ( ) , invalid_utf8. clone ( ) ) ;
660
+ assert_eq ! ( format!( "{}" , err) , format!( "{desc} at index {pos}: {cause}" , desc=err. description( ) , pos=cause. valid_up_to( ) , cause=cause) ) ;
661
+ assert_eq ! ( format!( "{:?}" , err) , format!( "FromUtf8Error({:?}, {:?})" , cause, invalid_utf8) ) ;
662
+ assert_eq ! ( err. description( ) , "utf8 error" ) ;
663
+ assert_eq ! ( format!( "{:?}" , err. cause( ) . unwrap( ) ) , format!( "{:?}" , cause) ) ;
685
664
}
686
665
687
666
#[ test]
688
- fn io_wrapper_from ( ) {
689
- let io1: IoWrapper = From :: from ( io:: Error :: from_raw_os_error ( 2 ) ) ;
690
- assert_eq ! ( format!( "{}" , io1) ,
691
- "I/O error: No such file or directory (os error 2)" . to_string( ) ) ;
692
- let descr = io1. cause ( ) . unwrap ( ) . description ( ) ;
693
- assert ! ( descr == "os error" // rust <= 1.6
694
- || descr == "entity not found" // rust 1.7 (probably, nightly)
695
- ) ;
667
+ fn wrapper_from ( ) {
668
+ let cause = "one and a half times pi" . parse :: < f32 > ( ) . unwrap_err ( ) ;
669
+ let err = Wrapper :: ParseFloatError ( cause. clone ( ) ) ;
670
+ let err_from: Wrapper = From :: from ( cause) ;
671
+ assert_eq ! ( err_from, err) ;
696
672
}
697
673
698
674
#[ test]
699
- fn io_wrapper_custom_from ( ) {
700
- let io1: IoWrapper = From :: from ( "Stringy" . to_string ( ) ) ;
701
- assert_eq ! ( format!( "{}" , io1) , "io error at idea: Stringy" . to_string( ) ) ;
702
- assert_eq ! ( io1. cause( ) . unwrap( ) . description( ) , "Stringy" ) ;
675
+ fn wrapper_custom_from ( ) {
676
+ let invalid_utf8: Vec < u8 > = vec ! [ 0 , 159 , 146 , 150 ] ;
677
+ let cause = String :: from_utf8 ( invalid_utf8. clone ( ) ) . unwrap_err ( ) ;
678
+ let err = Wrapper :: FromUtf8Error ( cause. utf8_error ( ) . clone ( ) , invalid_utf8) ;
679
+ let err_from: Wrapper = From :: from ( cause) ;
680
+ assert_eq ! ( err_from, err) ;
703
681
}
704
682
705
683
#[ test]
706
- fn io_wrapper_discard ( ) {
707
- let io1: IoWrapper = From :: from ( "hello" ) ;
708
- assert_eq ! ( format!( "{}" , io1) , "Discard" . to_string( ) ) ;
709
- assert ! ( io1. cause( ) . is_none( ) ) ;
684
+ fn wrapper_discard ( ) {
685
+ let err: Wrapper = From :: from ( "hello" ) ;
686
+ assert_eq ! ( format!( "{}" , err) , format!( "Discard" ) ) ;
687
+ assert_eq ! ( format!( "{:?}" , err) , format!( "Discard" ) ) ;
688
+ assert_eq ! ( err. description( ) , "Discard" ) ;
689
+ assert ! ( err. cause( ) . is_none( ) ) ;
710
690
}
711
691
712
692
#[ test]
713
- fn io_wrapper_signleton ( ) {
714
- let io1: IoWrapper = IoWrapper :: Singleton ;
715
- assert_eq ! ( format!( "{}" , io1) , "Just a string" . to_string( ) ) ;
693
+ fn wrapper_singleton ( ) {
694
+ let err: Wrapper = Wrapper :: Singleton ;
695
+ assert_eq ! ( format!( "{}" , err) , format!( "Just a string" ) ) ;
696
+ assert_eq ! ( format!( "{:?}" , err) , format!( "Singleton" ) ) ;
697
+ assert_eq ! ( err. description( ) , "Singleton" ) ;
698
+ assert ! ( err. cause( ) . is_none( ) ) ;
716
699
}
717
-
718
700
}
0 commit comments