xso: improve documentation around text traits for third-party types
The previous wording was a bit ominous in places ("Because of the
unfortunate situation as described in `FromXmlText`"). This should be
clearer and provides hopefully clearer instructions.
This commit is contained in:
parent
8688524e1a
commit
67e7e9da15
2 changed files with 89 additions and 23 deletions
|
|
@ -248,18 +248,13 @@ pub trait FromXml {
|
|||
|
||||
/// Trait allowing to convert XML text to a value.
|
||||
///
|
||||
/// This trait is similar to [`core::str::FromStr`], however, due to
|
||||
/// restrictions imposed by the orphan rule, a separate trait is needed.
|
||||
/// Implementations for many standard library types are available. In
|
||||
/// addition, the following feature flags can enable more implementations:
|
||||
/// This trait is similar to [`FromStr`][`core::str::FromStr`], however, to
|
||||
/// allow specialisation for XML<->Text conversion, a separate trait is
|
||||
/// introduced. Unlike `FromStr`, this trait allows taking ownership of the
|
||||
/// original text data, potentially saving allocations.
|
||||
///
|
||||
/// - `jid`: `jid::Jid`, `jid::BareJid`, `jid::FullJid`
|
||||
/// - `uuid`: `uuid::Uuid`
|
||||
///
|
||||
/// Because of this unfortunate situation, 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.
|
||||
/// **Important:** See the [`text`][`crate::text`] module's documentation
|
||||
/// for notes regarding implementations for types from third-party crates.
|
||||
pub trait FromXmlText: Sized {
|
||||
/// Convert the given XML text to a value.
|
||||
fn from_xml_text(data: String) -> Result<Self, self::error::Error>;
|
||||
|
|
@ -306,17 +301,8 @@ impl<T: FromXmlText> FromXmlText for Box<T> {
|
|||
/// serialisation in XML text, you should *only* implement
|
||||
/// [`AsOptionalXmlText`] and omit the [`AsXmlText`] implementation.
|
||||
///
|
||||
/// This trait is implemented for many standard library types implementing
|
||||
/// [`core::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.
|
||||
/// **Important:** See the [`text`][`crate::text`] module's documentation
|
||||
/// for notes regarding implementations for types from third-party crates.
|
||||
pub trait AsXmlText {
|
||||
/// Convert the value to an XML string in a context where an absent value
|
||||
/// cannot be represented.
|
||||
|
|
@ -380,6 +366,9 @@ impl<T: AsXmlText> AsXmlText for &T {
|
|||
/// If your type can be serialised as both (text and attribute) but needs
|
||||
/// special handling in attributes, implement [`AsXmlText`] but provide a
|
||||
/// custom implementation of [`AsXmlText::as_optional_xml_text`].
|
||||
///
|
||||
/// **Important:** See the [`text`][`crate::text`] module's documentation
|
||||
/// for notes regarding implementations for types from third-party crates.
|
||||
pub trait AsOptionalXmlText {
|
||||
/// Convert the value to an XML string in a context where an absent value
|
||||
/// can be represented.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,84 @@
|
|||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//! Module containing implementations for conversions to/from XML text.
|
||||
//! # Convert data to and from XML text
|
||||
//!
|
||||
//! This module provides traits and types related to conversion of XML text
|
||||
//! data to and from Rust types, as well as the [`AsXmlText`],
|
||||
//! [`AsOptionalXmlText`][`crate::AsOptionalXmlText`] and [`FromXmlText`]
|
||||
//! implementations for foreign and standard-library types.
|
||||
//!
|
||||
//! ## Support for types from third-party crates
|
||||
//!
|
||||
//! Beyond the standard library types, the following additional types are
|
||||
//! supported:
|
||||
//!
|
||||
//! | Feature gate | Types |
|
||||
//! | --- | --- |
|
||||
//! | `jid` | `jid::Jid`, `jid::BareJid`, `jid::FullJid` |
|
||||
//! | `serde_json` | `serde_json::Value` |
|
||||
//! | `uuid` | `uuid::Uuid` |
|
||||
//!
|
||||
//! ### Adding support for more types
|
||||
//!
|
||||
//! Due to the orphan rule, it is not possible for applications to implement
|
||||
//! [`AsXmlText`], [`AsOptionalXmlText`][`crate::AsOptionalXmlText`] or
|
||||
//! [`FromXmlText`] on types which originate from third-party crates. Because
|
||||
//! of that, we are **extremely liberal** at accepting merge requests for
|
||||
//! implementations of these traits for types from third-party crates.
|
||||
//!
|
||||
//! The only requirement is that the implementation is gated behind a feature
|
||||
//! flag which is disabled-by-default.
|
||||
//!
|
||||
//! ### Workaround for unsupported types
|
||||
//!
|
||||
//! If making a merge request against `xso` and waiting for a release is not
|
||||
//! an option, you can use newtype wrappers in almost all cases, for example:
|
||||
//!
|
||||
#![cfg_attr(
|
||||
not(all(feature = "std", feature = "macros")),
|
||||
doc = "Because the std or macros feature was not enabled at doc build time, the example cannot be tested.\n\n```ignore\n"
|
||||
)]
|
||||
#![cfg_attr(all(feature = "std", feature = "macros"), doc = "\n```\n")]
|
||||
//! # use xso::{AsXml, FromXml, AsXmlText, FromXmlText, error::Error};
|
||||
//! # use std::borrow::Cow;
|
||||
//! use std::process::ExitCode;
|
||||
//!
|
||||
//! struct MyExitCode(ExitCode);
|
||||
//!
|
||||
//! impl AsXmlText for MyExitCode {
|
||||
//! fn as_xml_text(&self) -> Result<Cow<'_, str>, Error> {
|
||||
//! match self.0 {
|
||||
//! ExitCode::FAILURE => Ok(Cow::Borrowed("failure")),
|
||||
//! ExitCode::SUCCESS => Ok(Cow::Borrowed("success")),
|
||||
//! _ => Err(Error::Other("unknown exit code")),
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! impl FromXmlText for MyExitCode {
|
||||
//! fn from_xml_text(s: String) -> Result<Self, Error> {
|
||||
//! match s.as_str() {
|
||||
//! "failure" => Ok(Self(ExitCode::FAILURE)),
|
||||
//! "success" => Ok(Self(ExitCode::SUCCESS)),
|
||||
//! _ => Err(Error::Other("unknown exit code")),
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(AsXml, FromXml)]
|
||||
//! #[xml(namespace = "urn:example", name = "process-result")]
|
||||
//! struct ProcessResult {
|
||||
//! #[xml(attribute)]
|
||||
//! code: MyExitCode,
|
||||
//! #[xml(text)]
|
||||
//! stdout: String,
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! Of course, such an approach reduces the usability of your struct (and
|
||||
//! comes with issues once references are needed), so making a merge request
|
||||
//! against `xso` is generally preferable.
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue