From 6dd096123d18dcae4c596def00edf9b778e6f01f Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Fri, 29 Apr 2022 18:01:35 +0200 Subject: [PATCH] Passing first test --- .gitignore | 2 ++ Cargo.toml | 2 ++ instant-xml-macros/Cargo.toml | 13 +++++++++++++ instant-xml-macros/src/lib.rs | 22 ++++++++++++++++++++++ instant-xml/Cargo.toml | 10 ++++++++++ instant-xml/src/lib.rs | 27 +++++++++++++++++++++++++++ instant-xml/tests/all.rs | 9 +++++++++ 7 files changed, 85 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 instant-xml-macros/Cargo.toml create mode 100644 instant-xml-macros/src/lib.rs create mode 100644 instant-xml/Cargo.toml create mode 100644 instant-xml/src/lib.rs create mode 100644 instant-xml/tests/all.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..0e49ca5 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,2 @@ +[workspace] +members = ["instant-xml", "instant-xml-macros"] diff --git a/instant-xml-macros/Cargo.toml b/instant-xml-macros/Cargo.toml new file mode 100644 index 0000000..22a14c5 --- /dev/null +++ b/instant-xml-macros/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "instant-xml-macros" +version = "0.1.0" +edition = "2021" +workspace = ".." + +[lib] +proc-macro = true + +[dependencies] +heck = "0.4" +quote = "1.0.18" +syn = { version = "1.0.86", features = ["full"] } diff --git a/instant-xml-macros/src/lib.rs b/instant-xml-macros/src/lib.rs new file mode 100644 index 0000000..73c4c9b --- /dev/null +++ b/instant-xml-macros/src/lib.rs @@ -0,0 +1,22 @@ +extern crate proc_macro; + +use proc_macro::TokenStream; +use quote::quote; +use syn::parse_macro_input; + +#[proc_macro_derive(ToXml)] +pub fn to_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 ToXml for #ident { + fn write_xml(&self, write: &mut W) -> Result<(), instant_xml::Error> { + write.write_str("<")?; + write.write_fmt(format_args!("{}", #name))?; + write.write_str("/>")?; + Ok(()) + } + } + )) +} diff --git a/instant-xml/Cargo.toml b/instant-xml/Cargo.toml new file mode 100644 index 0000000..20d3783 --- /dev/null +++ b/instant-xml/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "instant-xml" +version = "0.1.0" +edition = "2021" +workspace = ".." + +[dependencies] +macros = { package = "instant-xml-macros", version = "0.1", path = "../instant-xml-macros" } +thiserror = "1.0.29" +xmlparser = "0.13.3" diff --git a/instant-xml/src/lib.rs b/instant-xml/src/lib.rs new file mode 100644 index 0000000..c6c5cbc --- /dev/null +++ b/instant-xml/src/lib.rs @@ -0,0 +1,27 @@ +use std::fmt; + +use thiserror::Error; + +pub use macros::ToXml; + +pub trait ToXml { + fn write_xml(&self, write: &mut W) -> Result<(), Error>; + + fn to_xml(&self) -> Result { + let mut out = String::new(); + self.write_xml(&mut out)?; + Ok(out) + } +} + +pub trait FromXml<'xml>: Sized { + fn from_xml(input: &str) -> Result; +} + +pub trait FromXmlOwned: for<'xml> FromXml<'xml> {} + +#[derive(Debug, Error)] +pub enum Error { + #[error("format: {0}")] + Format(#[from] fmt::Error), +} diff --git a/instant-xml/tests/all.rs b/instant-xml/tests/all.rs new file mode 100644 index 0000000..b347244 --- /dev/null +++ b/instant-xml/tests/all.rs @@ -0,0 +1,9 @@ +use instant_xml::ToXml; + +#[derive(ToXml)] +struct Unit; + +#[test] +fn unit() { + assert_eq!(Unit.to_xml().unwrap(), ""); +}