Skip to content

Commit

Permalink
Implement Clone for error enums
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
zeenix committed Dec 8, 2022
1 parent 364e49d commit 003c7bc
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 16 deletions.
5 changes: 5 additions & 0 deletions Changelog.md
Expand Up @@ -14,6 +14,10 @@

### New Features

- [#521]: Implement `Clone` for all error types. This required changing `Error::Io` to contain
`Arc<std::io::Error>` instead of `std::io::Error` since `std::io::Error` does not implement
`Clone`.

### Bug Fixes

- [#490]: Ensure that serialization of map keys always produces valid XML names.
Expand Down Expand Up @@ -60,6 +64,7 @@
[#500]: https://github.com/tafia/quick-xml/issues/500
[#514]: https://github.com/tafia/quick-xml/issues/514
[#517]: https://github.com/tafia/quick-xml/issues/517
[#521]: https://github.com/tafia/quick-xml/pull/521
[XML name]: https://www.w3.org/TR/xml11/#NT-Name
[documentation]: https://docs.rs/quick-xml/0.27.0/quick_xml/de/index.html#difference-between-text-and-value-special-names

Expand Down
13 changes: 8 additions & 5 deletions src/errors.rs
Expand Up @@ -7,12 +7,15 @@ use std::fmt;
use std::io::Error as IoError;
use std::str::Utf8Error;
use std::string::FromUtf8Error;
use std::sync::Arc;

/// The error type used by this crate.
#[derive(Debug)]
#[derive(Clone, Debug)]
pub enum Error {
/// IO error
Io(IoError),
/// IO error.
///
/// `Arc<IoError>` instead of `IoError` since `IoError` is not `Clone`.
Io(Arc<IoError>),
/// Input decoding error. If `encoding` feature is disabled, contains `None`,
/// otherwise contains the UTF-8 decoding error
NonDecodable(Option<Utf8Error>),
Expand Down Expand Up @@ -45,7 +48,7 @@ impl From<IoError> for Error {
/// Creates a new `Error::Io` from the given error
#[inline]
fn from(error: IoError) -> Error {
Error::Io(error)
Error::Io(Arc::new(error))
}
}

Expand Down Expand Up @@ -140,7 +143,7 @@ pub mod serialize {
use std::num::{ParseFloatError, ParseIntError};

/// (De)serialization error
#[derive(Debug)]
#[derive(Clone, Debug)]
pub enum DeError {
/// Serde custom error
Custom(String),
Expand Down
2 changes: 1 addition & 1 deletion src/escapei.rs
Expand Up @@ -8,7 +8,7 @@ use std::ops::Range;
use pretty_assertions::assert_eq;

/// Error for XML escape / unescape.
#[derive(Debug)]
#[derive(Clone, Debug)]
pub enum EscapeError {
/// Entity with Null character
EntityWithNull(Range<usize>),
Expand Down
2 changes: 1 addition & 1 deletion src/events/attributes.rs
Expand Up @@ -241,7 +241,7 @@ impl<'a> FusedIterator for Attributes<'a> {}
///
/// Recovery position in examples shows the position from which parsing of the
/// next attribute will be attempted.
#[derive(Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum AttrError {
/// Attribute key was not followed by `=`, position relative to the start of
/// the owning tag is provided.
Expand Down
14 changes: 7 additions & 7 deletions src/reader/buffered_reader.rs
Expand Up @@ -27,7 +27,7 @@ macro_rules! impl_buffered_source {
Ok(())
},
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
Err(e) => Err(Error::Io(e)),
Err(e) => Err(Error::Io(e.into())),
};
}
}
Expand All @@ -43,7 +43,7 @@ macro_rules! impl_buffered_source {
Ok(None)
},
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
Err(e) => Err(Error::Io(e)),
Err(e) => Err(Error::Io(e.into())),
};
}
}
Expand All @@ -69,7 +69,7 @@ macro_rules! impl_buffered_source {
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
Err(e) => {
*position += read;
return Err(Error::Io(e));
return Err(Error::Io(e.into()));
}
};

Expand Down Expand Up @@ -136,7 +136,7 @@ macro_rules! impl_buffered_source {
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
Err(e) => {
*position += read;
return Err(Error::Io(e));
return Err(Error::Io(e.into()));
}
}
}
Expand Down Expand Up @@ -181,7 +181,7 @@ macro_rules! impl_buffered_source {
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
Err(e) => {
*position += read;
return Err(Error::Io(e));
return Err(Error::Io(e.into()));
}
};
}
Expand All @@ -207,7 +207,7 @@ macro_rules! impl_buffered_source {
}
}
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
Err(e) => Err(Error::Io(e)),
Err(e) => Err(Error::Io(e.into())),
};
}
}
Expand All @@ -232,7 +232,7 @@ macro_rules! impl_buffered_source {
Ok(n) if n.is_empty() => Ok(None),
Ok(n) => Ok(Some(n[0])),
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue,
Err(e) => Err(Error::Io(e)),
Err(e) => Err(Error::Io(e.into())),
};
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/writer.rs
Expand Up @@ -3,7 +3,7 @@
use std::io::Write;

use crate::encoding::UTF8_BOM;
use crate::errors::{Error, Result};
use crate::errors::Result;
use crate::events::{attributes::Attribute, BytesCData, BytesStart, BytesText, Event};

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

#[inline]
Expand Down

0 comments on commit 003c7bc

Please sign in to comment.