Skip to content

Commit 8025695

Browse files
committed
Implement Clone for error enums
This would allow using crates to embed errors from this crate into their error types that implement Clone. Unfortunately `std::io::Error` does not implement `Clone` [1] so we've to wrap it in an `Arc`.
1 parent 52f3d7f commit 8025695

File tree

6 files changed

+23
-16
lines changed

6 files changed

+23
-16
lines changed

Changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212

1313
### New Features
1414

15+
- Implement `Clone` for all error types. This required changing `Error::Io` to contain
16+
`Arc<std::io::Error>` instead of `std::io::Error` since `std::io::Error` does not implement
17+
`Clone`.
18+
1519
### Bug Fixes
1620

1721
- [#490]: Ensure that serialization of map keys always produces valid XML names.

src/errors.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ use std::fmt;
77
use std::io::Error as IoError;
88
use std::str::Utf8Error;
99
use std::string::FromUtf8Error;
10+
use std::sync::Arc;
1011

1112
/// The error type used by this crate.
12-
#[derive(Debug)]
13+
#[derive(Clone, Debug)]
1314
pub enum Error {
14-
/// IO error
15-
Io(IoError),
15+
/// IO error.
16+
///
17+
/// `Arc<IoError>` instead of `IoError` since `IoError` is not `Clone`.
18+
Io(Arc<IoError>),
1619
/// Input decoding error. If `encoding` feature is disabled, contains `None`,
1720
/// otherwise contains the UTF-8 decoding error
1821
NonDecodable(Option<Utf8Error>),
@@ -45,7 +48,7 @@ impl From<IoError> for Error {
4548
/// Creates a new `Error::Io` from the given error
4649
#[inline]
4750
fn from(error: IoError) -> Error {
48-
Error::Io(error)
51+
Error::Io(Arc::new(error))
4952
}
5053
}
5154

@@ -140,7 +143,7 @@ pub mod serialize {
140143
use std::num::{ParseFloatError, ParseIntError};
141144

142145
/// (De)serialization error
143-
#[derive(Debug)]
146+
#[derive(Clone, Debug)]
144147
pub enum DeError {
145148
/// Serde custom error
146149
Custom(String),

src/escapei.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::ops::Range;
88
use pretty_assertions::assert_eq;
99

1010
/// Error for XML escape / unescape.
11-
#[derive(Debug)]
11+
#[derive(Clone, Debug)]
1212
pub enum EscapeError {
1313
/// Entity with Null character
1414
EntityWithNull(Range<usize>),

src/events/attributes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ impl<'a> FusedIterator for Attributes<'a> {}
241241
///
242242
/// Recovery position in examples shows the position from which parsing of the
243243
/// next attribute will be attempted.
244-
#[derive(Debug, PartialEq, Eq)]
244+
#[derive(Clone, Debug, PartialEq, Eq)]
245245
pub enum AttrError {
246246
/// Attribute key was not followed by `=`, position relative to the start of
247247
/// the owning tag is provided.

src/reader/buffered_reader.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ macro_rules! impl_buffered_source {
2727
Ok(())
2828
},
2929
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
30-
Err(e) => Err(Error::Io(e)),
30+
Err(e) => Err(Error::Io(e.into())),
3131
};
3232
}
3333
}
@@ -43,7 +43,7 @@ macro_rules! impl_buffered_source {
4343
Ok(None)
4444
},
4545
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
46-
Err(e) => Err(Error::Io(e)),
46+
Err(e) => Err(Error::Io(e.into())),
4747
};
4848
}
4949
}
@@ -69,7 +69,7 @@ macro_rules! impl_buffered_source {
6969
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
7070
Err(e) => {
7171
*position += read;
72-
return Err(Error::Io(e));
72+
return Err(Error::Io(e.into()));
7373
}
7474
};
7575

@@ -136,7 +136,7 @@ macro_rules! impl_buffered_source {
136136
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
137137
Err(e) => {
138138
*position += read;
139-
return Err(Error::Io(e));
139+
return Err(Error::Io(e.into()));
140140
}
141141
}
142142
}
@@ -181,7 +181,7 @@ macro_rules! impl_buffered_source {
181181
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
182182
Err(e) => {
183183
*position += read;
184-
return Err(Error::Io(e));
184+
return Err(Error::Io(e.into()));
185185
}
186186
};
187187
}
@@ -207,7 +207,7 @@ macro_rules! impl_buffered_source {
207207
}
208208
}
209209
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
210-
Err(e) => Err(Error::Io(e)),
210+
Err(e) => Err(Error::Io(e.into())),
211211
};
212212
}
213213
}
@@ -232,7 +232,7 @@ macro_rules! impl_buffered_source {
232232
Ok(n) if n.is_empty() => Ok(None),
233233
Ok(n) => Ok(Some(n[0])),
234234
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
235-
Err(e) => Err(Error::Io(e)),
235+
Err(e) => Err(Error::Io(e.into())),
236236
};
237237
}
238238
}

src/writer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::io::Write;
44

55
use crate::encoding::UTF8_BOM;
6-
use crate::errors::{Error, Result};
6+
use crate::errors::Result;
77
use crate::events::{attributes::Attribute, BytesCData, BytesStart, BytesText, Event};
88

99
/// XML writer. Writes XML [`Event`]s to a [`std::io::Write`] implementor.
@@ -163,7 +163,7 @@ impl<W: Write> Writer<W> {
163163
/// Writes bytes
164164
#[inline]
165165
pub(crate) fn write(&mut self, value: &[u8]) -> Result<()> {
166-
self.writer.write_all(value).map_err(Error::Io)
166+
self.writer.write_all(value).map_err(Into::into)
167167
}
168168

169169
#[inline]

0 commit comments

Comments
 (0)