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
|
- `xso::convert_via_fromstr_and_display`, a declarative macro to provide
|
||||||
`AsXmlText` and `FromXmlText` implementations based on the standard
|
`AsXmlText` and `FromXmlText` implementations based on the standard
|
||||||
library's `Display` and `FromStr` traits.
|
library's `Display` and `FromStr` traits.
|
||||||
|
- `AsXmlDyn`, a dyn-compatible variant of `AsXml` (!573).
|
||||||
* Changes
|
* Changes
|
||||||
- Generated AsXml iterator and FromXml builder types are now
|
- Generated AsXml iterator and FromXml builder types are now
|
||||||
doc(hidden), to not clutter hand-written documentation with auto
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
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)]
|
#[doc(inline)]
|
||||||
pub use fromxml::Context;
|
pub use fromxml::Context;
|
||||||
|
|
@ -150,6 +150,22 @@ pub trait AsXml {
|
||||||
/// Return an iterator which emits the contents of the struct or enum as
|
/// Return an iterator which emits the contents of the struct or enum as
|
||||||
/// serialisable [`Item`] items.
|
/// serialisable [`Item`] items.
|
||||||
fn as_xml_iter(&self) -> Result<Self::ItemIter<'_>, self::error::Error>;
|
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
|
/// Trait for a temporary object allowing to construct a struct from
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue