Skip to content

Commit a6a9671

Browse files
committed
Make exif::Error Sync again to be compatible with anyhow::Error.
1 parent eeb65ec commit a6a9671

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
0.6.1
2+
3+
- `exif::Error` has been changed to be `Sync` again. It was
4+
unintentionally not so in 0.6.
5+
16
0.6 (2024-11-01)
27

38
- Rust 1.60 or later is now required to build this package.

src/error.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
use std::error;
2828
use std::fmt;
2929
use 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

118120
impl 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

129132
impl 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

Comments
 (0)