xso: reorganise the code a little
The main lib.rs is getting a bit cluttered, so I'm trying to bring some order into the chaos by moving some things into other modules. skip-changelog, because there are no user-facing changes (names which have been moved are doc(inline)'d and pub use'd in the main lib, and other things (trait implementations) aren't addressable by users).
This commit is contained in:
parent
4c47946b81
commit
8c7b503f12
3 changed files with 130 additions and 130 deletions
|
|
@ -15,7 +15,44 @@
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
|
|
||||||
use crate::error::{Error, FromEventsError};
|
use crate::error::{Error, FromEventsError};
|
||||||
use crate::{Context, FromEventsBuilder, FromXml};
|
use crate::{FromEventsBuilder, FromXml};
|
||||||
|
|
||||||
|
/// # Parsing context for [`FromEventsBuilder`]
|
||||||
|
///
|
||||||
|
/// For the most part, [`FromEventsBuilder`] implementations can work with
|
||||||
|
/// only the information inside the [`rxml::Event`] which is delivered to
|
||||||
|
/// them (and any information they may have stored from previous events).
|
||||||
|
///
|
||||||
|
/// However, there is (currently) one special case: the `xml:lang` attribute.
|
||||||
|
/// That attribute is inherited across the entire document tree hierarchy. If
|
||||||
|
/// the parsed element is not the top-level element, there may be an implicit
|
||||||
|
/// value for `xml:lang`.
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub struct Context<'x> {
|
||||||
|
language: Option<&'x str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'x> Context<'x> {
|
||||||
|
/// A context suitable for the beginning of the document.
|
||||||
|
///
|
||||||
|
/// `xml:lang` is assumed to be unset.
|
||||||
|
pub fn empty() -> Self {
|
||||||
|
Self { language: None }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the effective `xml:lang` value on the context and return it.
|
||||||
|
pub fn with_language(mut self, language: Option<&'x str>) -> Self {
|
||||||
|
self.language = language;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the `xml:lang` value in effect at the end of the event which
|
||||||
|
/// is currently being processed.
|
||||||
|
pub fn language(&self) -> Option<&str> {
|
||||||
|
self.language.as_deref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Helper struct to construct an `Option<T>` from XML events.
|
/// Helper struct to construct an `Option<T>` from XML events.
|
||||||
pub struct OptionBuilder<T: FromEventsBuilder>(T);
|
pub struct OptionBuilder<T: FromEventsBuilder>(T);
|
||||||
|
|
|
||||||
131
xso/src/lib.rs
131
xso/src/lib.rs
|
|
@ -100,12 +100,10 @@ pub mod exports {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use alloc::{
|
use alloc::{borrow::Cow, string::String, vec::Vec};
|
||||||
borrow::{Cow, ToOwned},
|
|
||||||
boxed::Box,
|
#[doc(inline)]
|
||||||
string::String,
|
pub use fromxml::Context;
|
||||||
vec::Vec,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub use text::TextCodec;
|
pub use text::TextCodec;
|
||||||
|
|
||||||
|
|
@ -154,42 +152,6 @@ pub trait AsXml {
|
||||||
fn as_xml_iter(&self) -> Result<Self::ItemIter<'_>, self::error::Error>;
|
fn as_xml_iter(&self) -> Result<Self::ItemIter<'_>, self::error::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Parsing context for [`FromEventsBuilder`]
|
|
||||||
///
|
|
||||||
/// For the most part, [`FromEventsBuilder`] implementations can work with
|
|
||||||
/// only the information inside the [`rxml::Event`] which is delivered to
|
|
||||||
/// them (and any information they may have stored from previous events).
|
|
||||||
///
|
|
||||||
/// However, there is (currently) one special case: the `xml:lang` attribute.
|
|
||||||
/// That attribute is inherited across the entire document tree hierarchy. If
|
|
||||||
/// the parsed element is not the top-level element, there may be an implicit
|
|
||||||
/// value for `xml:lang`.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Context<'x> {
|
|
||||||
language: Option<&'x str>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'x> Context<'x> {
|
|
||||||
/// A context suitable for the beginning of the document.
|
|
||||||
///
|
|
||||||
/// `xml:lang` is assumed to be unset.
|
|
||||||
pub fn empty() -> Self {
|
|
||||||
Self { language: None }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the effective `xml:lang` value on the context and return it.
|
|
||||||
pub fn with_language(mut self, language: Option<&'x str>) -> Self {
|
|
||||||
self.language = language;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the `xml:lang` value in effect at the end of the event which
|
|
||||||
/// is currently being processed.
|
|
||||||
pub fn language(&self) -> Option<&str> {
|
|
||||||
self.language.as_deref()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Trait for a temporary object allowing to construct a struct from
|
/// Trait for a temporary object allowing to construct a struct from
|
||||||
/// [`rxml::Event`] items.
|
/// [`rxml::Event`] items.
|
||||||
///
|
///
|
||||||
|
|
@ -277,34 +239,6 @@ pub trait FromXmlText: Sized {
|
||||||
fn from_xml_text(data: String) -> Result<Self, self::error::Error>;
|
fn from_xml_text(data: String) -> Result<Self, self::error::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromXmlText for String {
|
|
||||||
/// Return the string unchanged.
|
|
||||||
fn from_xml_text(data: String) -> Result<Self, self::error::Error> {
|
|
||||||
Ok(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: FromXmlText, B: ToOwned<Owned = T>> FromXmlText for Cow<'_, B> {
|
|
||||||
/// Return a [`Cow::Owned`] containing the parsed value.
|
|
||||||
fn from_xml_text(data: String) -> Result<Self, self::error::Error> {
|
|
||||||
Ok(Cow::Owned(T::from_xml_text(data)?))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: FromXmlText> FromXmlText for Option<T> {
|
|
||||||
/// Return a [`Some`] containing the parsed value.
|
|
||||||
fn from_xml_text(data: String) -> Result<Self, self::error::Error> {
|
|
||||||
Ok(Some(T::from_xml_text(data)?))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: FromXmlText> FromXmlText for Box<T> {
|
|
||||||
/// Return a [`Box`] containing the parsed value.
|
|
||||||
fn from_xml_text(data: String) -> Result<Self, self::error::Error> {
|
|
||||||
Ok(Box::new(T::from_xml_text(data)?))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Trait to convert a value to an XML text string.
|
/// Trait to convert a value to an XML text string.
|
||||||
///
|
///
|
||||||
/// Implementing this trait for a type allows it to be used both for XML
|
/// Implementing this trait for a type allows it to be used both for XML
|
||||||
|
|
@ -341,48 +275,6 @@ pub trait AsXmlText {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsXmlText for String {
|
|
||||||
/// Return the borrowed string contents.
|
|
||||||
fn as_xml_text(&self) -> Result<Cow<'_, str>, self::error::Error> {
|
|
||||||
Ok(Cow::Borrowed(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsXmlText for str {
|
|
||||||
/// Return the borrowed string contents.
|
|
||||||
fn as_xml_text(&self) -> Result<Cow<'_, str>, self::error::Error> {
|
|
||||||
Ok(Cow::Borrowed(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsXmlText for &str {
|
|
||||||
/// Return the borrowed string contents.
|
|
||||||
fn as_xml_text(&self) -> Result<Cow<'_, str>, self::error::Error> {
|
|
||||||
Ok(Cow::Borrowed(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: AsXmlText> AsXmlText for Box<T> {
|
|
||||||
/// Return the borrowed [`Box`] contents.
|
|
||||||
fn as_xml_text(&self) -> Result<Cow<'_, str>, self::error::Error> {
|
|
||||||
T::as_xml_text(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: AsXmlText + ToOwned> AsXmlText for Cow<'_, B> {
|
|
||||||
/// Return the borrowed [`Cow`] contents.
|
|
||||||
fn as_xml_text(&self) -> Result<Cow<'_, str>, self::error::Error> {
|
|
||||||
B::as_xml_text(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: AsXmlText> AsXmlText for &T {
|
|
||||||
/// Delegate to the `AsXmlText` implementation on `T`.
|
|
||||||
fn as_xml_text(&self) -> Result<Cow<'_, str>, self::error::Error> {
|
|
||||||
T::as_xml_text(*self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Specialized variant of [`AsXmlText`].
|
/// Specialized variant of [`AsXmlText`].
|
||||||
///
|
///
|
||||||
/// Normally, it should not be necessary to implement this trait as it is
|
/// Normally, it should not be necessary to implement this trait as it is
|
||||||
|
|
@ -407,21 +299,6 @@ pub trait AsOptionalXmlText {
|
||||||
fn as_optional_xml_text(&self) -> Result<Option<Cow<'_, str>>, self::error::Error>;
|
fn as_optional_xml_text(&self) -> Result<Option<Cow<'_, str>>, self::error::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsXmlText> AsOptionalXmlText for T {
|
|
||||||
fn as_optional_xml_text(&self) -> Result<Option<Cow<'_, str>>, self::error::Error> {
|
|
||||||
<Self as AsXmlText>::as_optional_xml_text(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: AsXmlText> AsOptionalXmlText for Option<T> {
|
|
||||||
fn as_optional_xml_text(&self) -> Result<Option<Cow<'_, str>>, self::error::Error> {
|
|
||||||
self.as_ref()
|
|
||||||
.map(T::as_optional_xml_text)
|
|
||||||
.transpose()
|
|
||||||
.map(Option::flatten)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// # Control how unknown attributes are handled
|
/// # Control how unknown attributes are handled
|
||||||
///
|
///
|
||||||
/// The variants of this enum are referenced in the
|
/// The variants of this enum are referenced in the
|
||||||
|
|
|
||||||
|
|
@ -86,13 +86,14 @@
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use alloc::{
|
use alloc::{
|
||||||
borrow::Cow,
|
borrow::{Cow, ToOwned},
|
||||||
|
boxed::Box,
|
||||||
format,
|
format,
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{error::Error, AsXmlText, FromXmlText};
|
use crate::{error::Error, AsOptionalXmlText, AsXmlText, FromXmlText};
|
||||||
|
|
||||||
#[cfg(feature = "base64")]
|
#[cfg(feature = "base64")]
|
||||||
use base64::engine::general_purpose::STANDARD as StandardBase64Engine;
|
use base64::engine::general_purpose::STANDARD as StandardBase64Engine;
|
||||||
|
|
@ -251,6 +252,91 @@ convert_via_fromstr_and_display! {
|
||||||
serde_json::Value,
|
serde_json::Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromXmlText for String {
|
||||||
|
/// Return the string unchanged.
|
||||||
|
fn from_xml_text(data: String) -> Result<Self, Error> {
|
||||||
|
Ok(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: FromXmlText, B: ToOwned<Owned = T>> FromXmlText for Cow<'_, B> {
|
||||||
|
/// Return a [`Cow::Owned`] containing the parsed value.
|
||||||
|
fn from_xml_text(data: String) -> Result<Self, Error> {
|
||||||
|
Ok(Cow::Owned(T::from_xml_text(data)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: FromXmlText> FromXmlText for Option<T> {
|
||||||
|
/// Return a [`Some`] containing the parsed value.
|
||||||
|
fn from_xml_text(data: String) -> Result<Self, Error> {
|
||||||
|
Ok(Some(T::from_xml_text(data)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: FromXmlText> FromXmlText for Box<T> {
|
||||||
|
/// Return a [`Box`] containing the parsed value.
|
||||||
|
fn from_xml_text(data: String) -> Result<Self, Error> {
|
||||||
|
Ok(Box::new(T::from_xml_text(data)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsXmlText for String {
|
||||||
|
/// Return the borrowed string contents.
|
||||||
|
fn as_xml_text(&self) -> Result<Cow<'_, str>, Error> {
|
||||||
|
Ok(Cow::Borrowed(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsXmlText for str {
|
||||||
|
/// Return the borrowed string contents.
|
||||||
|
fn as_xml_text(&self) -> Result<Cow<'_, str>, Error> {
|
||||||
|
Ok(Cow::Borrowed(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsXmlText for &str {
|
||||||
|
/// Return the borrowed string contents.
|
||||||
|
fn as_xml_text(&self) -> Result<Cow<'_, str>, Error> {
|
||||||
|
Ok(Cow::Borrowed(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: AsXmlText> AsXmlText for Box<T> {
|
||||||
|
/// Return the borrowed [`Box`] contents.
|
||||||
|
fn as_xml_text(&self) -> Result<Cow<'_, str>, Error> {
|
||||||
|
T::as_xml_text(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: AsXmlText + ToOwned> AsXmlText for Cow<'_, B> {
|
||||||
|
/// Return the borrowed [`Cow`] contents.
|
||||||
|
fn as_xml_text(&self) -> Result<Cow<'_, str>, Error> {
|
||||||
|
B::as_xml_text(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: AsXmlText> AsXmlText for &T {
|
||||||
|
/// Delegate to the `AsXmlText` implementation on `T`.
|
||||||
|
fn as_xml_text(&self) -> Result<Cow<'_, str>, Error> {
|
||||||
|
T::as_xml_text(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: AsXmlText> AsOptionalXmlText for T {
|
||||||
|
fn as_optional_xml_text(&self) -> Result<Option<Cow<'_, str>>, Error> {
|
||||||
|
<Self as AsXmlText>::as_optional_xml_text(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: AsXmlText> AsOptionalXmlText for Option<T> {
|
||||||
|
fn as_optional_xml_text(&self) -> Result<Option<Cow<'_, str>>, Error> {
|
||||||
|
self.as_ref()
|
||||||
|
.map(T::as_optional_xml_text)
|
||||||
|
.transpose()
|
||||||
|
.map(Option::flatten)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Represent a way to encode/decode text data into a Rust type.
|
/// Represent a way to encode/decode text data into a Rust type.
|
||||||
///
|
///
|
||||||
/// This trait can be used in scenarios where implementing [`FromXmlText`]
|
/// This trait can be used in scenarios where implementing [`FromXmlText`]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue