xso: add type-erased and dyn-compatible variant of AsXml
That way, we don't need to know the specific type of iterator or even iteree anymore. This can turn out useful when working with `Box<dyn _>`, that is, in contexts where we don't know the (possible or actual) types at compile time.
This commit is contained in:
parent
ee9ffb2d9c
commit
d7b62488dc
3 changed files with 40 additions and 1 deletions
|
|
@ -53,6 +53,7 @@ Version NEXT:
|
|||
- `xso::convert_via_fromstr_and_display`, a declarative macro to provide
|
||||
`AsXmlText` and `FromXmlText` implementations based on the standard
|
||||
library's `Display` and `FromStr` traits.
|
||||
- `AsXmlDyn`, a dyn-compatible variant of `AsXml` (!573).
|
||||
* Changes
|
||||
- Generated AsXml iterator and FromXml builder types are now
|
||||
doc(hidden), to not clutter hand-written documentation with auto
|
||||
|
|
|
|||
|
|
@ -127,6 +127,28 @@ impl<T: AsXml> fmt::Display for PrintRawXml<'_, T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Dyn-compatible version of [`AsXml`].
|
||||
///
|
||||
/// This trait is automatically implemented for all types which implement
|
||||
/// `AsXml`.
|
||||
pub trait AsXmlDyn {
|
||||
/// Return an iterator which emits the contents of the struct or enum as
|
||||
/// serialisable [`Item`] items.
|
||||
fn as_xml_dyn_iter<'x>(
|
||||
&'x self,
|
||||
) -> Result<Box<dyn Iterator<Item = Result<Item<'x>, Error>> + 'x>, Error>;
|
||||
}
|
||||
|
||||
impl<T: AsXml> AsXmlDyn for T {
|
||||
/// Return an iterator which emits the contents of the struct or enum as
|
||||
/// serialisable [`Item`] items by calling [`AsXml::as_xml_dyn_iter`].
|
||||
fn as_xml_dyn_iter<'x>(
|
||||
&'x self,
|
||||
) -> Result<Box<dyn Iterator<Item = Result<Item<'x>, Error>> + 'x>, Error> {
|
||||
<T as AsXml>::as_xml_dyn_iter(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ pub mod exports {
|
|||
}
|
||||
}
|
||||
|
||||
use alloc::{borrow::Cow, string::String, vec::Vec};
|
||||
use alloc::{borrow::Cow, boxed::Box, string::String, vec::Vec};
|
||||
|
||||
#[doc(inline)]
|
||||
pub use fromxml::Context;
|
||||
|
|
@ -150,6 +150,22 @@ pub trait AsXml {
|
|||
/// Return an iterator which emits the contents of the struct or enum as
|
||||
/// serialisable [`Item`] items.
|
||||
fn as_xml_iter(&self) -> Result<Self::ItemIter<'_>, self::error::Error>;
|
||||
|
||||
/// Return the same iterator as [`as_xml_iter`][`Self::as_xml_iter`], but
|
||||
/// boxed to erase the concrete iterator type.
|
||||
///
|
||||
/// The provided implementation uses a simple cast. In most cases, it does
|
||||
/// not make sense to override the implementation. The only exception is
|
||||
/// if [`Self::ItemIter`] is already a boxed type, in which case
|
||||
/// overriding this method can avoid double-boxing the iterator.
|
||||
fn as_xml_dyn_iter<'x>(
|
||||
&'x self,
|
||||
) -> Result<
|
||||
Box<dyn Iterator<Item = Result<Item<'x>, self::error::Error>> + 'x>,
|
||||
self::error::Error,
|
||||
> {
|
||||
self.as_xml_iter().map(|x| Box::new(x) as Box<_>)
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for a temporary object allowing to construct a struct from
|
||||
|
|
|
|||
Loading…
Reference in a new issue