xso: only take reference in transform
This avoids the need for an expensive clone. Since we switched to AsXml instead of IntoXml, we don't necessarily have to clone the data when building new elements, only when it's absolutely necessary. The clones then happen implicitly in the ItemToEvent iterator used internally. This mostly fixes #86, with the caveat that there's no absolutely cheap test: On success, the entire element will be copied, while on failure, you learn about it rather quickly.
This commit is contained in:
parent
9901141b5f
commit
58698f633f
4 changed files with 16 additions and 4 deletions
|
|
@ -29,8 +29,7 @@ mod helpers {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => panic!("failed to parse from {:?}: {}", s, e),
|
Err(e) => panic!("failed to parse from {:?}: {}", s, e),
|
||||||
};
|
};
|
||||||
let recovered =
|
let recovered = transform(&structural).expect("roundtrip did not produce an element");
|
||||||
transform(structural.clone()).expect("roundtrip did not produce an element");
|
|
||||||
assert_eq!(initial, recovered);
|
assert_eq!(initial, recovered);
|
||||||
let structural2: T = match try_from_element(recovered) {
|
let structural2: T = match try_from_element(recovered) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,12 @@ fn as_xml_impl(input: Item) -> Result<TokenStream> {
|
||||||
result.extend(quote! {
|
result.extend(quote! {
|
||||||
impl ::core::convert::From<#ident> for ::xso::exports::minidom::Element {
|
impl ::core::convert::From<#ident> for ::xso::exports::minidom::Element {
|
||||||
fn from(other: #ident) -> Self {
|
fn from(other: #ident) -> Self {
|
||||||
|
::xso::transform(&other).expect("seamless conversion into minidom::Element")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::core::convert::From<&#ident> for ::xso::exports::minidom::Element {
|
||||||
|
fn from(other: &#ident) -> Self {
|
||||||
::xso::transform(other).expect("seamless conversion into minidom::Element")
|
::xso::transform(other).expect("seamless conversion into minidom::Element")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -163,6 +169,13 @@ fn as_xml_impl(input: Item) -> Result<TokenStream> {
|
||||||
type Error = ::xso::error::Error;
|
type Error = ::xso::error::Error;
|
||||||
|
|
||||||
fn try_from(other: #ident) -> ::core::result::Result<Self, Self::Error> {
|
fn try_from(other: #ident) -> ::core::result::Result<Self, Self::Error> {
|
||||||
|
::xso::transform(&other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ::core::convert::TryFrom<&#ident> for ::xso::exports::minidom::Element {
|
||||||
|
type Error = ::xso::error::Error;
|
||||||
|
|
||||||
|
fn try_from(other: &#ident) -> ::core::result::Result<Self, Self::Error> {
|
||||||
::xso::transform(other)
|
::xso::transform(other)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -381,7 +381,7 @@ impl UnknownChildPolicy {
|
||||||
|
|
||||||
/// Attempt to transform a type implementing [`AsXml`] into another
|
/// Attempt to transform a type implementing [`AsXml`] into another
|
||||||
/// type which implements [`FromXml`].
|
/// type which implements [`FromXml`].
|
||||||
pub fn transform<T: FromXml, F: AsXml>(from: F) -> Result<T, self::error::Error> {
|
pub fn transform<T: FromXml, F: AsXml>(from: &F) -> Result<T, self::error::Error> {
|
||||||
let mut iter = self::rxml_util::ItemToEvent::new(from.as_xml_iter()?);
|
let mut iter = self::rxml_util::ItemToEvent::new(from.as_xml_iter()?);
|
||||||
let (qname, attrs) = match iter.next() {
|
let (qname, attrs) = match iter.next() {
|
||||||
Some(Ok(rxml::Event::StartElement(_, qname, attrs))) => (qname, attrs),
|
Some(Ok(rxml::Event::StartElement(_, qname, attrs))) => (qname, attrs),
|
||||||
|
|
|
||||||
|
|
@ -475,7 +475,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn transform_element_is_equivalent() {
|
fn transform_element_is_equivalent() {
|
||||||
let el: Element = "<foo xmlns='urn:a' a='b' c='d'><child a='x'/><child a='y'>some text</child><child xmlns='urn:b'><nested-child/></child></foo>".parse().unwrap();
|
let el: Element = "<foo xmlns='urn:a' a='b' c='d'><child a='x'/><child a='y'>some text</child><child xmlns='urn:b'><nested-child/></child></foo>".parse().unwrap();
|
||||||
let transformed: Element = crate::transform(el.clone()).unwrap();
|
let transformed: Element = crate::transform(&el).unwrap();
|
||||||
assert_eq!(el, transformed);
|
assert_eq!(el, transformed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue