Passing extended first test
This commit is contained in:
parent
6dd096123d
commit
b5b5d376c2
|
@ -20,3 +20,21 @@ pub fn to_xml(input: TokenStream) -> TokenStream {
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(FromXml)]
|
||||||
|
pub fn from_xml(input: TokenStream) -> TokenStream {
|
||||||
|
let ast = parse_macro_input!(input as syn::ItemStruct);
|
||||||
|
let ident = &ast.ident;
|
||||||
|
let name = ident.to_string();
|
||||||
|
TokenStream::from(quote!(
|
||||||
|
impl<'xml> FromXml<'xml> for #ident {
|
||||||
|
fn from_xml(input: &str) -> Result<Self, ::instant_xml::Error> {
|
||||||
|
use ::instant_xml::parse::Parse;
|
||||||
|
let mut iter = ::instant_xml::xmlparser::Tokenizer::from(input);
|
||||||
|
iter.next().element_start(None, #name)?;
|
||||||
|
iter.next().element_end(None, #name)?;
|
||||||
|
Ok(Self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
pub use xmlparser as xmlparser;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
pub use macros::ToXml;
|
pub use macros::{FromXml, ToXml};
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub mod parse;
|
||||||
|
|
||||||
pub trait ToXml {
|
pub trait ToXml {
|
||||||
fn write_xml<W: fmt::Write>(&self, write: &mut W) -> Result<(), Error>;
|
fn write_xml<W: fmt::Write>(&self, write: &mut W) -> Result<(), Error>;
|
||||||
|
@ -20,8 +25,18 @@ pub trait FromXml<'xml>: Sized {
|
||||||
|
|
||||||
pub trait FromXmlOwned: for<'xml> FromXml<'xml> {}
|
pub trait FromXmlOwned: for<'xml> FromXml<'xml> {}
|
||||||
|
|
||||||
|
struct State<'a> {
|
||||||
|
prefix: HashMap<&'a str, &'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("format: {0}")]
|
#[error("format: {0}")]
|
||||||
Format(#[from] fmt::Error),
|
Format(#[from] fmt::Error),
|
||||||
|
#[error("parse: {0}")]
|
||||||
|
Parse(#[from] xmlparser::Error),
|
||||||
|
#[error("unexpected end of stream")]
|
||||||
|
UnexpectedEndOfStream,
|
||||||
|
#[error("unexpected value")]
|
||||||
|
UnexpectedValue,
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
use xmlparser::{Token, ElementEnd};
|
||||||
|
|
||||||
|
use super::Error;
|
||||||
|
|
||||||
|
impl<'a> Parse for Option<Result<xmlparser::Token<'a>, xmlparser::Error>> {
|
||||||
|
fn element_start(self, ns: Option<&str>, tag: &str) -> Result<(), Error> {
|
||||||
|
match self {
|
||||||
|
Some(Ok(Token::ElementStart { prefix, local, .. })) => {
|
||||||
|
let prefix_ns = prefix.as_str();
|
||||||
|
let (has_prefix, expect_prefix) = (!prefix_ns.is_empty(), ns.is_some());
|
||||||
|
if has_prefix != expect_prefix {
|
||||||
|
return dbg!(Err(Error::UnexpectedValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
if has_prefix && Some(prefix_ns) != ns {
|
||||||
|
return dbg!(Err(Error::UnexpectedValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
if local.as_str() != tag {
|
||||||
|
return dbg!(Err(Error::UnexpectedValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Some(Ok(_)) => Err(Error::UnexpectedValue),
|
||||||
|
Some(Err(err)) => Err(err.into()),
|
||||||
|
None => Err(Error::UnexpectedEndOfStream),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn element_end(self, _: Option<&str>, _: &str) -> Result<(), Error> {
|
||||||
|
match self {
|
||||||
|
Some(Ok(Token::ElementEnd { end, .. })) => {
|
||||||
|
match end {
|
||||||
|
ElementEnd::Open => todo!(),
|
||||||
|
ElementEnd::Close(_, _) => todo!(),
|
||||||
|
ElementEnd::Empty => return Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(Ok(_)) => Err(Error::UnexpectedValue),
|
||||||
|
Some(Err(err)) => Err(err.into()),
|
||||||
|
None => Err(Error::UnexpectedEndOfStream),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Parse {
|
||||||
|
fn element_start(self, ns: Option<&str>, tag: &str) -> Result<(), Error>;
|
||||||
|
fn element_end(self, ns: Option<&str>, tag: &str) -> Result<(), Error>;
|
||||||
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
use instant_xml::ToXml;
|
use instant_xml::{FromXml, ToXml};
|
||||||
|
|
||||||
#[derive(ToXml)]
|
#[derive(Debug, Eq, FromXml, PartialEq, ToXml)]
|
||||||
struct Unit;
|
struct Unit;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unit() {
|
fn unit() {
|
||||||
assert_eq!(Unit.to_xml().unwrap(), "<Unit/>");
|
assert_eq!(Unit.to_xml().unwrap(), "<Unit/>");
|
||||||
|
assert_eq!(Unit::from_xml("<Unit/>").unwrap(), Unit);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue