113
113
//! }
114
114
//! ```
115
115
//!
116
+ //! If you need a reference to the error when `Display`ing, you can instead use
117
+ //! `display(x) -> (pattern, ..args)`, where `x` sets the name of the reference.
118
+ //!
119
+ //! ```rust
120
+ //! # #[macro_use] extern crate quick_error;
121
+ //! # fn main() {}
122
+ //! #
123
+ //! use std::error::Error; // put methods like `description()` of this trait into scope
124
+ //!
125
+ //! quick_error! {
126
+ //! #[derive(Debug)]
127
+ //! pub enum SomeError {
128
+ //! Io(err: std::io::Error) {
129
+ //! display(x) -> ("{}: {}", x.description(), err)
130
+ //! }
131
+ //! Utf8(err: std::str::Utf8Error) {
132
+ //! display(self_) -> ("{}, valid up to {}", self_.description(), err.valid_up_to())
133
+ //! }
134
+ //! }
135
+ //! }
136
+ //! ```
137
+ //!
116
138
//! To convert to the type from any other, use one of the three forms of
117
139
//! `from` clause.
118
140
//!
181
203
//! Empty braces can be omitted as of quick_error 0.1.3.
182
204
//!
183
205
184
-
185
206
/// Main macro that does all the work
186
207
#[ macro_export]
187
208
macro_rules! quick_error {
@@ -376,9 +397,11 @@ macro_rules! quick_error {
376
397
match self {
377
398
$(
378
399
& $name:: $item $( ( $( ref $var) ,* ) ) * => {
379
- quick_error!( FIND_DISPLAY_IMPL
380
- $item self fmt [ $( ( $( $var) * ) ) * ]
381
- { $( $funcs) * } )
400
+ let display_fn = quick_error!( FIND_DISPLAY_IMPL
401
+ $name $item
402
+ { $( $funcs) * } ) ;
403
+
404
+ display_fn( self , fmt)
382
405
}
383
406
) *
384
407
}
@@ -415,25 +438,34 @@ macro_rules! quick_error {
415
438
{ $( $funcs) * } ) ;
416
439
) *
417
440
} ;
418
- ( FIND_DISPLAY_IMPL $item: ident $me: ident $fmt: ident
419
- [ $( ( $( $var: ident) * ) ) * ]
420
- { display( $( $exprs: tt) * ) $( $tail: tt) * }
441
+ ( FIND_DISPLAY_IMPL $name: ident $item: ident
442
+ { display( $self_: tt) -> ( $( $exprs: tt) * ) $( $tail: tt) * }
421
443
) => {
422
- write! ( $ fmt, $( $exprs) * )
444
+ |quick_error! ( IDENT $self_ ) : & $name , f : & mut :: std :: fmt:: Formatter | { write! ( f , $( $exprs) * ) }
423
445
} ;
424
- ( FIND_DISPLAY_IMPL $item: ident $me: ident $fmt: ident
425
- [ $( ( $( $var: ident) * ) ) * ]
446
+ ( FIND_DISPLAY_IMPL $name: ident $item: ident
447
+ { display( $pattern: expr) $( $tail: tt) * }
448
+ ) => {
449
+ |_, f: & mut :: std:: fmt:: Formatter | { write!( f, $pattern) }
450
+ } ;
451
+ ( FIND_DISPLAY_IMPL $name: ident $item: ident
452
+ { display( $pattern: expr, $( $exprs: tt) * ) $( $tail: tt) * }
453
+ ) => {
454
+ |_, f: & mut :: std:: fmt:: Formatter | { write!( f, $pattern, $( $exprs) * ) }
455
+ } ;
456
+ ( FIND_DISPLAY_IMPL $name: ident $item: ident
426
457
{ $t: tt $( $tail: tt) * }
427
458
) => {
428
459
quick_error!( FIND_DISPLAY_IMPL
429
- $item $me $fmt [ $ ( ( $ ( $var ) * ) ) * ]
460
+ $name $item
430
461
{ $( $tail) * } )
431
462
} ;
432
- ( FIND_DISPLAY_IMPL $item: ident $me: ident $fmt: ident
433
- [ $( ( $( $var: ident) * ) ) * ]
463
+ ( FIND_DISPLAY_IMPL $name: ident $item: ident
434
464
{ }
435
465
) => {
436
- write!( $fmt, "{}" , :: std:: error:: Error :: description( $me) )
466
+ |self_: & $name, f: & mut :: std:: fmt:: Formatter | {
467
+ write!( f, "{}" , :: std:: error:: Error :: description( self_) )
468
+ }
437
469
} ;
438
470
( FIND_DESCRIPTION_IMPL $item: ident $me: ident $fmt: ident
439
471
[ $( ( $( $var: ident) * ) ) * ]
@@ -533,7 +565,11 @@ macro_rules! quick_error {
533
565
// anything else.
534
566
// This is to contrast FIND_* clauses which just find stuff they need and
535
567
// skip everything else completely
536
- ( ERROR_CHECK display( $( $exprs: tt) * ) $( $tail: tt) * )
568
+ ( ERROR_CHECK display( $self_: tt) -> ( $( $exprs: tt) * ) $( $tail: tt) * )
569
+ => { quick_error!( ERROR_CHECK $( $tail) * ) ; } ;
570
+ ( ERROR_CHECK display( $pattern: expr) $( $tail: tt) * )
571
+ => { quick_error!( ERROR_CHECK $( $tail) * ) ; } ;
572
+ ( ERROR_CHECK display( $pattern: expr, $( $exprs: tt) * ) $( $tail: tt) * )
537
573
=> { quick_error!( ERROR_CHECK $( $tail) * ) ; } ;
538
574
( ERROR_CHECK description( $expr: expr) $( $tail: tt) * )
539
575
=> { quick_error!( ERROR_CHECK $( $tail) * ) ; } ;
@@ -546,6 +582,8 @@ macro_rules! quick_error {
546
582
( ERROR_CHECK from( $fvar: ident : $ftyp: ty) -> ( $( $e: expr) ,* ) $( $tail: tt) * )
547
583
=> { quick_error!( ERROR_CHECK $( $tail) * ) ; } ;
548
584
( ERROR_CHECK ) => { } ;
585
+ // Utility functions
586
+ ( IDENT $ident: ident) => { $ident }
549
587
}
550
588
551
589
#[ cfg( test) ]
@@ -594,14 +632,17 @@ mod test {
594
632
/// I/O error with some context
595
633
IoAt ( place: & ' static str , err: io:: Error ) {
596
634
cause( err)
597
- display( "Error at {} : {}", place, err)
635
+ display( self_ ) -> ( "{} {} : {}", self_ . description ( ) , place, err)
598
636
description( "io error at" )
599
637
from( s: String ) -> ( "idea" ,
600
638
io:: Error :: new( io:: ErrorKind :: Other , s) )
601
639
}
602
640
Discard {
603
641
from( & ' static str )
604
642
}
643
+ Singleton {
644
+ display( "Just a string" )
645
+ }
605
646
}
606
647
}
607
648
@@ -633,7 +674,7 @@ mod test {
633
674
let err: & Error = & IoWrapper :: IoAt ( "file" ,
634
675
io:: Error :: new ( io:: ErrorKind :: NotFound , io1) ) ;
635
676
assert_eq ! ( format!( "{}" , err) ,
636
- "Error at file: I/O error: some error" . to_string( ) ) ;
677
+ "io error at file: I/O error: some error" . to_string( ) ) ;
637
678
assert_eq ! ( format!( "{:?}" , err) , "IoAt(\" file\" , Error { \
638
679
repr: Custom(Custom { kind: NotFound, \
639
680
error: Io(Error { repr: Custom(Custom { \
@@ -657,7 +698,7 @@ mod test {
657
698
#[ test]
658
699
fn io_wrapper_custom_from ( ) {
659
700
let io1: IoWrapper = From :: from ( "Stringy" . to_string ( ) ) ;
660
- assert_eq ! ( format!( "{}" , io1) , "Error at idea: Stringy" . to_string( ) ) ;
701
+ assert_eq ! ( format!( "{}" , io1) , "io error at idea: Stringy" . to_string( ) ) ;
661
702
assert_eq ! ( io1. cause( ) . unwrap( ) . description( ) , "Stringy" ) ;
662
703
}
663
704
@@ -668,4 +709,10 @@ mod test {
668
709
assert ! ( io1. cause( ) . is_none( ) ) ;
669
710
}
670
711
712
+ #[ test]
713
+ fn io_wrapper_signleton ( ) {
714
+ let io1: IoWrapper = IoWrapper :: Singleton ;
715
+ assert_eq ! ( format!( "{}" , io1) , "Just a string" . to_string( ) ) ;
716
+ }
717
+
671
718
}
0 commit comments