2727use std:: error;
2828use std:: fmt;
2929use std:: io;
30+ use std:: sync:: Mutex ;
3031
3132/// An error returned when parsing of Exif data fails.
3233#[ derive( Debug ) ]
@@ -65,7 +66,7 @@ impl Error {
6566 pub fn distill_partial_result < F > ( self , f : F ) -> Result < crate :: Exif , Self >
6667 where F : FnOnce ( Vec < Error > ) {
6768 if let Error :: PartialResult ( partial) = self {
68- let ( exif, errors) = * partial. 0 ;
69+ let ( exif, errors) = partial. into_inner ( ) ;
6970 f ( errors) ;
7071 Ok ( exif)
7172 } else {
@@ -92,7 +93,8 @@ impl fmt::Display for Error {
9293 Error :: UnexpectedValue ( msg) => f. write_str ( msg) ,
9394 Error :: PartialResult ( ref pr) =>
9495 write ! ( f, "Partial result with {} fields and {} errors" ,
95- pr. 0.0 . fields( ) . len( ) , pr. 0.1 . len( ) ) ,
96+ pr. 0.0 . lock( ) . expect( "should not panic" ) . fields( ) . len( ) ,
97+ pr. 0.1 . len( ) ) ,
9698 }
9799 }
98100}
@@ -113,22 +115,37 @@ impl error::Error for Error {
113115}
114116
115117/// Partially-parsed result and errors.
116- pub struct PartialResult ( Box < ( crate :: Exif , Vec < Error > ) > ) ;
118+ pub struct PartialResult ( Box < ( Mutex < crate :: Exif > , Vec < Error > ) > ) ;
117119
118120impl PartialResult {
119121 pub ( crate ) fn new ( exif : crate :: Exif , errors : Vec < Error > ) -> Self {
120- Self ( Box :: new ( ( exif, errors) ) )
122+ Self ( Box :: new ( ( Mutex :: new ( exif) , errors) ) )
121123 }
122124
123125 /// Returns partially-parsed `Exif` and ignored `Error`s.
124126 pub fn into_inner ( self ) -> ( crate :: Exif , Vec < Error > ) {
125- * self . 0
127+ let ( exif, errors) = * self . 0 ;
128+ ( exif. into_inner ( ) . expect ( "should not panic" ) , errors)
126129 }
127130}
128131
129132impl fmt:: Debug for PartialResult {
130133 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
131134 write ! ( f, "PartialResult(Exif({} fields), {:?})" ,
132- self . 0.0 . fields( ) . len( ) , self . 0.1 )
135+ self . 0.0 . lock( ) . expect( "should not panic" ) . fields( ) . len( ) ,
136+ self . 0.1 )
137+ }
138+ }
139+
140+ #[ cfg( test) ]
141+ mod tests {
142+ use super :: * ;
143+
144+ // Check compatibility with anyhow::Error, which requires Send, Sync,
145+ // and 'static on error types.
146+ #[ test]
147+ fn is_send_sync_static ( ) {
148+ let _: Box < dyn Send + Sync + ' static > =
149+ Box :: new ( Error :: InvalidFormat ( "test" ) ) ;
133150 }
134151}
0 commit comments