xso: remove remnants of IntoXml
This commit is contained in:
parent
ccf38cdf9b
commit
7bc7e7a684
3 changed files with 13 additions and 157 deletions
|
|
@ -58,27 +58,6 @@ pub use xso_proc::FromXml;
|
||||||
#[cfg(feature = "macros")]
|
#[cfg(feature = "macros")]
|
||||||
pub use xso_proc::AsXml;
|
pub use xso_proc::AsXml;
|
||||||
|
|
||||||
/// Trait allowing to consume a struct and iterate its contents as
|
|
||||||
/// serialisable [`rxml::Event`] items.
|
|
||||||
///
|
|
||||||
/// **Important:** Changing the [`EventIter`][`Self::EventIter`] associated
|
|
||||||
/// type is considered a non-breaking change for any given implementation of
|
|
||||||
/// this trait. Always refer to a type's iterator type using fully-qualified
|
|
||||||
/// notation, for example: `<T as xso::IntoXml>::EventIter`.
|
|
||||||
pub trait IntoXml {
|
|
||||||
/// The iterator type.
|
|
||||||
///
|
|
||||||
/// **Important:** Changing this type is considered a non-breaking change
|
|
||||||
/// for any given implementation of this trait. Always refer to a type's
|
|
||||||
/// iterator type using fully-qualified notation, for example:
|
|
||||||
/// `<T as xso::IntoXml>::EventIter`.
|
|
||||||
type EventIter: Iterator<Item = Result<rxml::Event, self::error::Error>>;
|
|
||||||
|
|
||||||
/// Return an iterator which emits the contents of the struct or enum as
|
|
||||||
/// serialisable [`rxml::Event`] items.
|
|
||||||
fn into_event_iter(self) -> Result<Self::EventIter, self::error::Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Trait allowing to iterate a struct's contents as serialisable
|
/// Trait allowing to iterate a struct's contents as serialisable
|
||||||
/// [`Item`]s.
|
/// [`Item`]s.
|
||||||
///
|
///
|
||||||
|
|
@ -208,83 +187,6 @@ impl<T: FromXmlText> FromXmlText for Box<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait to convert a value to an XML text string.
|
|
||||||
///
|
|
||||||
/// This trait is implemented for many standard library types implementing
|
|
||||||
/// [`std::fmt::Display`]. In addition, the following feature flags can enable
|
|
||||||
/// more implementations:
|
|
||||||
///
|
|
||||||
/// - `jid`: `jid::Jid`, `jid::BareJid`, `jid::FullJid`
|
|
||||||
/// - `uuid`: `uuid::Uuid`
|
|
||||||
///
|
|
||||||
/// Because of the unfortunate situation as described in [`FromXmlText`], we
|
|
||||||
/// are **extremely liberal** with accepting optional dependencies for this
|
|
||||||
/// purpose. You are very welcome to make merge requests against this crate
|
|
||||||
/// adding support for parsing third-party crates.
|
|
||||||
pub trait IntoXmlText: Sized {
|
|
||||||
/// Convert the value to an XML string in a context where an absent value
|
|
||||||
/// cannot be represented.
|
|
||||||
fn into_xml_text(self) -> Result<String, self::error::Error>;
|
|
||||||
|
|
||||||
/// Convert the value to an XML string in a context where an absent value
|
|
||||||
/// can be represented.
|
|
||||||
///
|
|
||||||
/// The provided implementation will always return the result of
|
|
||||||
/// [`Self::into_xml_text`] wrapped into `Some(.)`. By re-implementing
|
|
||||||
/// this method, implementors can customize the behaviour for certain
|
|
||||||
/// values.
|
|
||||||
fn into_optional_xml_text(self) -> Result<Option<String>, self::error::Error> {
|
|
||||||
Ok(Some(self.into_xml_text()?))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoXmlText for String {
|
|
||||||
fn into_xml_text(self) -> Result<String, self::error::Error> {
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: IntoXmlText> IntoXmlText for Box<T> {
|
|
||||||
fn into_xml_text(self) -> Result<String, self::error::Error> {
|
|
||||||
T::into_xml_text(*self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: IntoXmlText, B: ToOwned<Owned = T>> IntoXmlText for Cow<'_, B> {
|
|
||||||
fn into_xml_text(self) -> Result<String, self::error::Error> {
|
|
||||||
T::into_xml_text(self.into_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Specialized variant of [`IntoXmlText`].
|
|
||||||
///
|
|
||||||
/// Do **not** implement this unless you cannot implement [`IntoXmlText`]:
|
|
||||||
/// implementing [`IntoXmlText`] is more versatile and an
|
|
||||||
/// [`IntoOptionalXmlText`] implementation is automatically provided.
|
|
||||||
///
|
|
||||||
/// If you need to customize the behaviour of the [`IntoOptionalXmlText`]
|
|
||||||
/// blanket implementation, implement a custom
|
|
||||||
/// [`IntoXmlText::into_optional_xml_text`] instead.
|
|
||||||
pub trait IntoOptionalXmlText {
|
|
||||||
/// Convert the value to an XML string in a context where an absent value
|
|
||||||
/// can be represented.
|
|
||||||
fn into_optional_xml_text(self) -> Result<Option<String>, self::error::Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: IntoXmlText> IntoOptionalXmlText for T {
|
|
||||||
fn into_optional_xml_text(self) -> Result<Option<String>, self::error::Error> {
|
|
||||||
<Self as IntoXmlText>::into_optional_xml_text(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: IntoOptionalXmlText> IntoOptionalXmlText for Option<T> {
|
|
||||||
fn into_optional_xml_text(self) -> Result<Option<String>, self::error::Error> {
|
|
||||||
self.map(T::into_optional_xml_text)
|
|
||||||
.transpose()
|
|
||||||
.map(Option::flatten)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Trait to convert a value to an XML text string.
|
/// Trait to convert a value to an XML text string.
|
||||||
///
|
///
|
||||||
/// This trait is implemented for many standard library types implementing
|
/// This trait is implemented for many standard library types implementing
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ use rxml::{
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{Error, FromEventsError},
|
error::{Error, FromEventsError},
|
||||||
rxml_util::{EventToItem, Item},
|
rxml_util::{EventToItem, Item},
|
||||||
AsXml, FromEventsBuilder, FromXml, IntoXml,
|
AsXml, FromEventsBuilder, FromXml,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// State machine for converting a minidom Element into rxml events.
|
/// State machine for converting a minidom Element into rxml events.
|
||||||
|
|
@ -115,7 +115,7 @@ impl IntoEventsInner {
|
||||||
return Ok(Some(Event::Text(EventMetrics::zero(), text)));
|
return Ok(Some(Event::Text(EventMetrics::zero(), text)));
|
||||||
}
|
}
|
||||||
Some(Node::Element(el)) => {
|
Some(Node::Element(el)) => {
|
||||||
*nested = Some(Box::new(el.into_event_iter()?));
|
*nested = Some(Box::new(IntoEvents::new(el)));
|
||||||
// fallthrough to next loop iteration
|
// fallthrough to next loop iteration
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
|
@ -136,7 +136,13 @@ impl IntoEventsInner {
|
||||||
/// This can be constructed from the
|
/// This can be constructed from the
|
||||||
/// [`IntoXml::into_event_iter`][`crate::IntoXml::into_event_iter`]
|
/// [`IntoXml::into_event_iter`][`crate::IntoXml::into_event_iter`]
|
||||||
/// implementation on [`minidom::Element`].
|
/// implementation on [`minidom::Element`].
|
||||||
pub struct IntoEvents(IntoEventsInner);
|
struct IntoEvents(IntoEventsInner);
|
||||||
|
|
||||||
|
impl IntoEvents {
|
||||||
|
fn new(el: Element) -> Self {
|
||||||
|
IntoEvents(IntoEventsInner::Header(el))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Iterator for IntoEvents {
|
impl Iterator for IntoEvents {
|
||||||
type Item = Result<Event, Error>;
|
type Item = Result<Event, Error>;
|
||||||
|
|
@ -146,14 +152,6 @@ impl Iterator for IntoEvents {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoXml for Element {
|
|
||||||
type EventIter = IntoEvents;
|
|
||||||
|
|
||||||
fn into_event_iter(self) -> Result<Self::EventIter, Error> {
|
|
||||||
Ok(IntoEvents(IntoEventsInner::Header(self)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum AsXmlState<'a> {
|
enum AsXmlState<'a> {
|
||||||
/// Element header: we need to generate the
|
/// Element header: we need to generate the
|
||||||
/// [`Item::ElementHeadStart`] item from the namespace and name.
|
/// [`Item::ElementHeadStart`] item from the namespace and name.
|
||||||
|
|
@ -425,38 +423,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper struct to stream a struct which implements conversion
|
|
||||||
/// to [`minidom::Element`].
|
|
||||||
pub struct IntoEventsViaElement {
|
|
||||||
inner: IntoEvents,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoEventsViaElement {
|
|
||||||
/// Create a new streaming parser for `T`.
|
|
||||||
pub fn new<E, T>(value: T) -> Result<Self, crate::error::Error>
|
|
||||||
where
|
|
||||||
Error: From<E>,
|
|
||||||
minidom::Element: TryFrom<T, Error = E>,
|
|
||||||
{
|
|
||||||
let element: minidom::Element = value.try_into()?;
|
|
||||||
Ok(Self {
|
|
||||||
inner: element.into_event_iter()?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Iterator for IntoEventsViaElement {
|
|
||||||
type Item = Result<Event, Error>;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
self.inner.next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper struct to stream a struct which implements conversion
|
/// Helper struct to stream a struct which implements conversion
|
||||||
/// to [`minidom::Element`].
|
/// to [`minidom::Element`].
|
||||||
pub struct AsItemsViaElement<'x> {
|
pub struct AsItemsViaElement<'x> {
|
||||||
iter: EventToItem<IntoEventsViaElement>,
|
iter: EventToItem<IntoEvents>,
|
||||||
lifetime_binding: PhantomData<Item<'x>>,
|
lifetime_binding: PhantomData<Item<'x>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -467,8 +437,9 @@ impl<'x> AsItemsViaElement<'x> {
|
||||||
Error: From<E>,
|
Error: From<E>,
|
||||||
minidom::Element: TryFrom<T, Error = E>,
|
minidom::Element: TryFrom<T, Error = E>,
|
||||||
{
|
{
|
||||||
|
let element: minidom::Element = value.try_into()?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
iter: EventToItem::new(IntoEventsViaElement::new(value)?),
|
iter: EventToItem::new(IntoEvents::new(element)),
|
||||||
lifetime_binding: PhantomData,
|
lifetime_binding: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use core::marker::PhantomData;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use crate::{error::Error, AsXmlText, FromXmlText, IntoXmlText};
|
use crate::{error::Error, AsXmlText, FromXmlText};
|
||||||
|
|
||||||
#[cfg(feature = "base64")]
|
#[cfg(feature = "base64")]
|
||||||
use base64::engine::{general_purpose::STANDARD as StandardBase64Engine, Engine as _};
|
use base64::engine::{general_purpose::STANDARD as StandardBase64Engine, Engine as _};
|
||||||
|
|
@ -33,16 +33,6 @@ macro_rules! convert_via_fromstr_and_display {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$(
|
|
||||||
#[cfg(feature = $feature)]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = $feature)))]
|
|
||||||
)?
|
|
||||||
impl IntoXmlText for $t {
|
|
||||||
fn into_xml_text(self) -> Result<String, Error> {
|
|
||||||
Ok(self.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$(
|
$(
|
||||||
#[cfg(feature = $feature)]
|
#[cfg(feature = $feature)]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = $feature)))]
|
#[cfg_attr(docsrs, doc(cfg(feature = $feature)))]
|
||||||
|
|
@ -69,13 +59,6 @@ impl FromXmlText for bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This provides an implementation compliant with xsd::bool.
|
|
||||||
impl IntoXmlText for bool {
|
|
||||||
fn into_xml_text(self) -> Result<String, Error> {
|
|
||||||
Ok(self.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This provides an implementation compliant with xsd::bool.
|
/// This provides an implementation compliant with xsd::bool.
|
||||||
impl AsXmlText for bool {
|
impl AsXmlText for bool {
|
||||||
fn as_xml_text(&self) -> Result<Cow<'_, str>, Error> {
|
fn as_xml_text(&self) -> Result<Cow<'_, str>, Error> {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue