cyberstorm/src/util/xml.rs

65 lines
1.6 KiB
Rust

use core::convert::TryFrom;
use core::fmt;
use roxmltree::Document;
use zc::{Dependant, Zc};
pub use roxmltree::{self, *};
pub struct DocumentBuf(Zc<String, DependantDocument<'static>>);
impl DocumentBuf {
pub fn document<'input>(&'input self) -> &Document<'input> {
&self.0.get::<DependantDocument<'input>>().0
}
}
impl fmt::Debug for DocumentBuf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.document(), f)
}
}
impl TryFrom<String> for DocumentBuf {
type Error = roxmltree::Error;
fn try_from(s: String) -> Result<Self, Self::Error> {
match zc::try_from!(s, DependantDocument, str) {
Ok(doc) => Ok(Self(doc)),
Err((err, _)) => Err(err),
}
}
}
impl serde::ser::Serialize for DocumentBuf {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
serializer.serialize_str(self.0.as_owned())
}
}
impl<'de> serde::de::Deserialize<'de> for DocumentBuf {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
use serde::de::Error;
Self::try_from(String::deserialize(deserializer)?).map_err(D::Error::custom)
}
}
struct DependantDocument<'input>(Document<'input>);
unsafe impl<'o> Dependant<'o> for DependantDocument<'o> {
type Static = DependantDocument<'static>;
}
impl<'input> TryFrom<&'input str> for DependantDocument<'input> {
type Error = roxmltree::Error;
fn try_from(s: &'input str) -> Result<Self, Self::Error> {
Document::parse(s).map(Self)
}
}