commit
2ee3dcda42
@ -48,7 +48,7 @@ impl<'de, R: Read> Deserializer<R> {
|
||||
if let Some(ref next) = self.peeked {
|
||||
Ok(next)
|
||||
} else {
|
||||
Err(String::from("unable to peek next item"))
|
||||
Err("unable to peek next item".into())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -19,13 +19,12 @@ pub mod ser;
|
||||
|
||||
/// A **data structure** that can be deserialized from any data format supported by YaSerDe.
|
||||
pub trait YaDeserialize: Sized {
|
||||
fn deserialize<R: Read>(reader: &mut de::Deserializer<R>) -> Result<Self, std::string::String>;
|
||||
fn deserialize<R: Read>(reader: &mut de::Deserializer<R>) -> Result<Self, String>;
|
||||
}
|
||||
|
||||
/// A **data structure** that can be serialized into any data format supported by YaSerDe.
|
||||
pub trait YaSerialize: Sized {
|
||||
fn serialize<W: Write>(&self, writer: &mut ser::Serializer<W>)
|
||||
-> Result<(), std::string::String>;
|
||||
fn serialize<W: Write>(&self, writer: &mut ser::Serializer<W>) -> Result<(), String>;
|
||||
|
||||
fn serialize_attributes(
|
||||
&self,
|
||||
@ -36,7 +35,7 @@ pub trait YaSerialize: Sized {
|
||||
Vec<xml::attribute::OwnedAttribute>,
|
||||
xml::namespace::Namespace,
|
||||
),
|
||||
std::string::String,
|
||||
String,
|
||||
>;
|
||||
}
|
||||
|
||||
@ -45,51 +44,51 @@ pub trait Visitor<'de>: Sized {
|
||||
/// The value produced by this visitor.
|
||||
type Value;
|
||||
|
||||
fn visit_bool(self, v: &str) -> Result<Self::Value, std::string::String> {
|
||||
fn visit_bool(self, v: &str) -> Result<Self::Value, String> {
|
||||
Err(format!("Unexpected bool {:?}", v))
|
||||
}
|
||||
|
||||
fn visit_i8(self, v: &str) -> Result<Self::Value, std::string::String> {
|
||||
fn visit_i8(self, v: &str) -> Result<Self::Value, String> {
|
||||
Err(format!("Unexpected i8 {:?}", v))
|
||||
}
|
||||
|
||||
fn visit_u8(self, v: &str) -> Result<Self::Value, std::string::String> {
|
||||
fn visit_u8(self, v: &str) -> Result<Self::Value, String> {
|
||||
Err(format!("Unexpected u8 {:?}", v))
|
||||
}
|
||||
|
||||
fn visit_i16(self, v: &str) -> Result<Self::Value, std::string::String> {
|
||||
fn visit_i16(self, v: &str) -> Result<Self::Value, String> {
|
||||
Err(format!("Unexpected i16 {:?}", v))
|
||||
}
|
||||
|
||||
fn visit_u16(self, v: &str) -> Result<Self::Value, std::string::String> {
|
||||
fn visit_u16(self, v: &str) -> Result<Self::Value, String> {
|
||||
Err(format!("Unexpected u16 {:?}", v))
|
||||
}
|
||||
|
||||
fn visit_i32(self, v: &str) -> Result<Self::Value, std::string::String> {
|
||||
fn visit_i32(self, v: &str) -> Result<Self::Value, String> {
|
||||
Err(format!("Unexpected i32 {:?}", v))
|
||||
}
|
||||
|
||||
fn visit_u32(self, v: &str) -> Result<Self::Value, std::string::String> {
|
||||
fn visit_u32(self, v: &str) -> Result<Self::Value, String> {
|
||||
Err(format!("Unexpected u32 {:?}", v))
|
||||
}
|
||||
|
||||
fn visit_i64(self, v: &str) -> Result<Self::Value, std::string::String> {
|
||||
fn visit_i64(self, v: &str) -> Result<Self::Value, String> {
|
||||
Err(format!("Unexpected i64 {:?}", v))
|
||||
}
|
||||
|
||||
fn visit_u64(self, v: &str) -> Result<Self::Value, std::string::String> {
|
||||
fn visit_u64(self, v: &str) -> Result<Self::Value, String> {
|
||||
Err(format!("Unexpected u64 {:?}", v))
|
||||
}
|
||||
|
||||
fn visit_f32(self, v: &str) -> Result<Self::Value, std::string::String> {
|
||||
fn visit_f32(self, v: &str) -> Result<Self::Value, String> {
|
||||
Err(format!("Unexpected f32 {:?}", v))
|
||||
}
|
||||
|
||||
fn visit_f64(self, v: &str) -> Result<Self::Value, std::string::String> {
|
||||
fn visit_f64(self, v: &str) -> Result<Self::Value, String> {
|
||||
Err(format!("Unexpected f64 {:?}", v))
|
||||
}
|
||||
|
||||
fn visit_str(self, v: &str) -> Result<Self::Value, std::string::String> {
|
||||
fn visit_str(self, v: &str) -> Result<Self::Value, String> {
|
||||
Err(format!("Unexpected str {:?}", v))
|
||||
}
|
||||
}
|
||||
@ -97,10 +96,7 @@ pub trait Visitor<'de>: Sized {
|
||||
macro_rules! serialize_type {
|
||||
($type:ty) => {
|
||||
impl YaSerialize for $type {
|
||||
fn serialize<W: Write>(
|
||||
&self,
|
||||
writer: &mut ser::Serializer<W>,
|
||||
) -> Result<(), std::string::String> {
|
||||
fn serialize<W: Write>(&self, writer: &mut ser::Serializer<W>) -> Result<(), String> {
|
||||
let content = format!("{}", self);
|
||||
let event = XmlEvent::characters(&content);
|
||||
let _ret = writer.write(event);
|
||||
@ -116,7 +112,7 @@ macro_rules! serialize_type {
|
||||
Vec<xml::attribute::OwnedAttribute>,
|
||||
xml::namespace::Namespace,
|
||||
),
|
||||
std::string::String,
|
||||
String,
|
||||
> {
|
||||
Ok((attributes, namespace))
|
||||
}
|
||||
@ -182,9 +178,10 @@ mod testing {
|
||||
let model = Data { item: $value };
|
||||
|
||||
let content = if let Some(str_value) = $content {
|
||||
std::string::String::from("<data><item>") + str_value + "</item></data>"
|
||||
let str_value: &str = str_value;
|
||||
format!("<data><item>{}</item></data>", str_value)
|
||||
} else {
|
||||
std::string::String::from("<data />")
|
||||
"<data />".to_owned()
|
||||
};
|
||||
|
||||
serialize_and_validate!(model, content);
|
||||
@ -218,7 +215,7 @@ mod testing {
|
||||
macro_rules! deserialize_and_validate {
|
||||
($content: expr, $model: expr, $struct: tt) => {
|
||||
log::debug!("deserialize_and_validate @ {}:{}", file!(), line!());
|
||||
let loaded: Result<$struct, std::string::String> = yaserde::de::from_str($content);
|
||||
let loaded: Result<$struct, String> = yaserde::de::from_str($content);
|
||||
assert_eq!(loaded, Ok($model));
|
||||
};
|
||||
}
|
||||
@ -227,18 +224,12 @@ mod testing {
|
||||
macro_rules! serialize_and_validate {
|
||||
($model: expr, $content: expr) => {
|
||||
log::debug!("serialize_and_validate @ {}:{}", file!(), line!());
|
||||
let data: Result<std::string::String, std::string::String> = yaserde::ser::to_string(&$model);
|
||||
let data: Result<String, String> = yaserde::ser::to_string(&$model);
|
||||
|
||||
let content =
|
||||
std::string::String::from(r#"<?xml version="1.0" encoding="utf-8"?>"#) + &$content;
|
||||
let content = format!(r#"<?xml version="1.0" encoding="utf-8"?>{}"#, $content);
|
||||
assert_eq!(
|
||||
data,
|
||||
Ok(
|
||||
std::string::String::from(content)
|
||||
.split("\n")
|
||||
.map(|s| s.trim())
|
||||
.collect::<std::string::String>()
|
||||
)
|
||||
Ok(content.split("\n").map(|s| s.trim()).collect::<String>())
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@ -11,14 +11,14 @@ pub fn to_string<T: YaSerialize>(model: &T) -> Result<String, String> {
|
||||
let buf = Cursor::new(Vec::new());
|
||||
let cursor = serialize_with_writer(model, buf, &Config::default())?;
|
||||
let data = str::from_utf8(cursor.get_ref()).expect("Found invalid UTF-8");
|
||||
Ok(std::string::String::from(data))
|
||||
Ok(data.into())
|
||||
}
|
||||
|
||||
pub fn to_string_with_config<T: YaSerialize>(model: &T, config: &Config) -> Result<String, String> {
|
||||
let buf = Cursor::new(Vec::new());
|
||||
let cursor = serialize_with_writer(model, buf, config)?;
|
||||
let data = str::from_utf8(cursor.get_ref()).expect("Found invalid UTF-8");
|
||||
Ok(std::string::String::from(data))
|
||||
Ok(data.into())
|
||||
}
|
||||
|
||||
pub fn serialize_with_writer<W: Write, T: YaSerialize>(
|
||||
@ -37,7 +37,7 @@ pub fn to_string_content<T: YaSerialize>(model: &T) -> Result<String, String> {
|
||||
let buf = Cursor::new(Vec::new());
|
||||
let cursor = serialize_with_writer_content(model, buf)?;
|
||||
let data = str::from_utf8(cursor.get_ref()).expect("Found invalid UTF-8");
|
||||
Ok(std::string::String::from(data))
|
||||
Ok(data.into())
|
||||
}
|
||||
|
||||
pub fn serialize_with_writer_content<W: Write, T: YaSerialize>(
|
||||
|
||||
@ -3,9 +3,6 @@ extern crate yaserde;
|
||||
#[macro_use]
|
||||
extern crate yaserde_derive;
|
||||
|
||||
use std::io::{Read, Write};
|
||||
use yaserde::{YaDeserialize, YaSerialize};
|
||||
|
||||
fn init() {
|
||||
let _ = env_logger::builder().is_test(true).try_init();
|
||||
}
|
||||
@ -128,8 +125,6 @@ fn module_inclusion() {
|
||||
init();
|
||||
|
||||
mod module {
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Default, PartialEq, YaDeserialize, YaSerialize)]
|
||||
#[yaserde(rename = "module")]
|
||||
pub struct Module {
|
||||
|
||||
@ -4,9 +4,9 @@ extern crate yaserde;
|
||||
extern crate yaserde_derive;
|
||||
|
||||
use log::debug;
|
||||
use std::io::{Read, Write};
|
||||
use std::io::Read;
|
||||
use yaserde::de::from_str;
|
||||
use yaserde::{YaDeserialize, YaSerialize};
|
||||
use yaserde::YaDeserialize;
|
||||
|
||||
fn init() {
|
||||
let _ = env_logger::builder().is_test(true).try_init();
|
||||
@ -15,7 +15,7 @@ fn init() {
|
||||
macro_rules! convert_and_validate {
|
||||
($content: expr, $struct: tt, $model: expr) => {
|
||||
debug!("convert_and_validate @ {}:{}", file!(), line!());
|
||||
let loaded: Result<$struct, std::string::String> = from_str($content);
|
||||
let loaded: Result<$struct, String> = from_str($content);
|
||||
assert_eq!(loaded, Ok($model));
|
||||
};
|
||||
}
|
||||
@ -37,8 +37,8 @@ fn de_basic() {
|
||||
content,
|
||||
Book,
|
||||
Book {
|
||||
author: String::from("Antoine de Saint-Exupéry"),
|
||||
title: String::from("Little prince"),
|
||||
author: "Antoine de Saint-Exupéry".to_owned(),
|
||||
title: "Little prince".to_owned(),
|
||||
}
|
||||
);
|
||||
|
||||
@ -48,8 +48,8 @@ fn de_basic() {
|
||||
content,
|
||||
Book,
|
||||
Book {
|
||||
author: String::from("Antoine de Saint-Exupéry"),
|
||||
title: String::from("Little prince"),
|
||||
author: "Antoine de Saint-Exupéry".to_owned(),
|
||||
title: "Little prince".to_owned(),
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -93,8 +93,8 @@ fn de_dash_param() {
|
||||
content,
|
||||
Book,
|
||||
Book {
|
||||
author: String::from("Antoine de Saint-Exupéry"),
|
||||
title: String::from("Little prince"),
|
||||
author: "Antoine de Saint-Exupéry".to_owned(),
|
||||
title: "Little prince".to_owned(),
|
||||
}
|
||||
);
|
||||
|
||||
@ -104,8 +104,8 @@ fn de_dash_param() {
|
||||
content,
|
||||
Book,
|
||||
Book {
|
||||
author: String::from("Antoine de Saint-Exupéry"),
|
||||
title: String::from("Little prince"),
|
||||
author: "Antoine de Saint-Exupéry".to_owned(),
|
||||
title: "Little prince".to_owned(),
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -115,21 +115,18 @@ fn de_multiple_segments() {
|
||||
init();
|
||||
|
||||
mod other_mod {
|
||||
use std::io::Read;
|
||||
use yaserde::YaDeserialize;
|
||||
|
||||
#[derive(YaDeserialize, PartialEq, Debug, Default)]
|
||||
pub struct Page {
|
||||
pub number: i32,
|
||||
pub text: std::string::String,
|
||||
pub text: String,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(YaDeserialize, PartialEq, Debug)]
|
||||
#[yaserde(root = "book")]
|
||||
pub struct Book {
|
||||
author: std::string::String,
|
||||
title: std::string::String,
|
||||
author: String,
|
||||
title: String,
|
||||
page: other_mod::Page,
|
||||
}
|
||||
|
||||
@ -148,11 +145,11 @@ fn de_multiple_segments() {
|
||||
content,
|
||||
Book,
|
||||
Book {
|
||||
author: String::from("Antoine de Saint-Exupéry"),
|
||||
title: String::from("Little prince"),
|
||||
author: "Antoine de Saint-Exupéry".to_owned(),
|
||||
title: "Little prince".to_owned(),
|
||||
page: other_mod::Page {
|
||||
number: 40,
|
||||
text: String::from("The Earth is not just an ordinary planet!"),
|
||||
text: "The Earth is not just an ordinary planet!".to_owned(),
|
||||
},
|
||||
}
|
||||
);
|
||||
@ -173,7 +170,7 @@ fn de_list_of_items() {
|
||||
content,
|
||||
Library,
|
||||
Library {
|
||||
books: vec![String::from("Little Prince"), String::from("Harry Potter")],
|
||||
books: vec!["Little Prince".to_owned(), "Harry Potter".to_owned()],
|
||||
}
|
||||
);
|
||||
|
||||
@ -190,10 +187,10 @@ fn de_list_of_items() {
|
||||
Libraries {
|
||||
library: vec![
|
||||
Library {
|
||||
books: vec![String::from("Little Prince")],
|
||||
books: vec!["Little Prince".to_owned()],
|
||||
},
|
||||
Library {
|
||||
books: vec![String::from("Harry Potter")],
|
||||
books: vec!["Harry Potter".to_owned()],
|
||||
},
|
||||
],
|
||||
}
|
||||
@ -280,7 +277,7 @@ fn de_attributes_custom_deserializer() {
|
||||
#[derive(Default, YaDeserialize, PartialEq, Debug)]
|
||||
pub struct Struct {
|
||||
#[yaserde(attribute)]
|
||||
attr_option_string: Option<std::string::String>,
|
||||
attr_option_string: Option<String>,
|
||||
#[yaserde(attribute)]
|
||||
attr_option_struct: Option<other_mod::Attributes>,
|
||||
}
|
||||
@ -311,8 +308,6 @@ fn de_attributes_complex() {
|
||||
init();
|
||||
|
||||
mod other_mod {
|
||||
use super::*;
|
||||
|
||||
#[derive(YaDeserialize, PartialEq, Debug)]
|
||||
pub enum AttrEnum {
|
||||
#[yaserde(rename = "variant 1")]
|
||||
@ -331,7 +326,7 @@ fn de_attributes_complex() {
|
||||
#[derive(Default, YaDeserialize, PartialEq, Debug)]
|
||||
pub struct Struct {
|
||||
#[yaserde(attribute)]
|
||||
attr_option_string: Option<std::string::String>,
|
||||
attr_option_string: Option<String>,
|
||||
#[yaserde(attribute)]
|
||||
attr_option_enum: Option<other_mod::AttrEnum>,
|
||||
}
|
||||
@ -564,7 +559,7 @@ fn de_complex_enum() {
|
||||
pub enum Color {
|
||||
White,
|
||||
Black(String),
|
||||
Orange(std::string::String),
|
||||
Orange(String),
|
||||
Red(i32),
|
||||
Green(OtherStruct),
|
||||
Yellow(Option<String>),
|
||||
@ -595,7 +590,7 @@ fn de_complex_enum() {
|
||||
content,
|
||||
XmlStruct,
|
||||
XmlStruct {
|
||||
background: Color::Black(String::from("text")),
|
||||
background: Color::Black("text".to_owned()),
|
||||
}
|
||||
);
|
||||
|
||||
@ -610,7 +605,7 @@ fn de_complex_enum() {
|
||||
content,
|
||||
XmlStruct,
|
||||
XmlStruct {
|
||||
background: Color::Orange(String::from("text")),
|
||||
background: Color::Orange("text".to_owned()),
|
||||
}
|
||||
);
|
||||
|
||||
@ -658,7 +653,7 @@ fn de_complex_enum() {
|
||||
content,
|
||||
XmlStruct,
|
||||
XmlStruct {
|
||||
background: Color::Yellow(Some(String::from("text"))),
|
||||
background: Color::Yellow(Some("text".to_owned())),
|
||||
}
|
||||
);
|
||||
|
||||
@ -692,7 +687,7 @@ fn de_complex_enum() {
|
||||
content,
|
||||
XmlStruct,
|
||||
XmlStruct {
|
||||
background: Color::Blue(vec![String::from("abc"), String::from("def")]),
|
||||
background: Color::Blue(vec!["abc".to_owned(), "def".to_owned()]),
|
||||
}
|
||||
);
|
||||
|
||||
@ -781,7 +776,7 @@ fn de_name_issue_21() {
|
||||
content,
|
||||
Book,
|
||||
Book {
|
||||
name: String::from("Little prince"),
|
||||
name: "Little prince".to_owned(),
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -806,13 +801,11 @@ fn de_custom() {
|
||||
}
|
||||
|
||||
impl YaDeserialize for Day {
|
||||
fn deserialize<R: Read>(
|
||||
reader: &mut yaserde::de::Deserializer<R>,
|
||||
) -> Result<Self, std::string::String> {
|
||||
fn deserialize<R: Read>(reader: &mut yaserde::de::Deserializer<R>) -> Result<Self, String> {
|
||||
use std::str::FromStr;
|
||||
|
||||
if let xml::reader::XmlEvent::StartElement { name, .. } = reader.peek()?.to_owned() {
|
||||
let expected_name = String::from("Day");
|
||||
let expected_name = "Day".to_owned();
|
||||
if name.local_name != expected_name {
|
||||
return Err(format!(
|
||||
"Wrong StartElement name: {}, expected: {}",
|
||||
|
||||
@ -3,9 +3,6 @@ extern crate yaserde;
|
||||
#[macro_use]
|
||||
extern crate yaserde_derive;
|
||||
|
||||
use std::io::{Read, Write};
|
||||
use yaserde::{YaDeserialize, YaSerialize};
|
||||
|
||||
#[test]
|
||||
fn basic_enum() {
|
||||
#[derive(Debug, PartialEq, YaDeserialize, YaSerialize)]
|
||||
@ -168,7 +165,7 @@ fn unnamed_enum() {
|
||||
pub enum Enum {
|
||||
Simple,
|
||||
Field(String),
|
||||
FullPath(std::string::String),
|
||||
FullPath(String),
|
||||
Integer(i32),
|
||||
UserStruct(OtherStruct),
|
||||
OptionString(Option<String>),
|
||||
@ -189,7 +186,7 @@ fn unnamed_enum() {
|
||||
}
|
||||
|
||||
let model = XmlStruct {
|
||||
color: Enum::Field(String::from("some_text")),
|
||||
color: Enum::Field("some_text".to_owned()),
|
||||
};
|
||||
|
||||
let content = "<base><color><Field>some_text</Field></color></base>";
|
||||
@ -197,7 +194,7 @@ fn unnamed_enum() {
|
||||
deserialize_and_validate!(content, model, XmlStruct);
|
||||
|
||||
let model = XmlStruct {
|
||||
color: Enum::FullPath(String::from("some_text")),
|
||||
color: Enum::FullPath("some_text".to_owned()),
|
||||
};
|
||||
|
||||
let content = "<base><color><FullPath>some_text</FullPath></color></base>";
|
||||
@ -221,7 +218,7 @@ fn unnamed_enum() {
|
||||
deserialize_and_validate!(content, model, XmlStruct);
|
||||
|
||||
let model = XmlStruct {
|
||||
color: Enum::OptionString(Some(String::from("some_text"))),
|
||||
color: Enum::OptionString(Some("some_text".to_owned())),
|
||||
};
|
||||
|
||||
let content = "<base><color><OptionString>some_text</OptionString></color></base>";
|
||||
@ -256,7 +253,7 @@ fn unnamed_enum() {
|
||||
// deserialize_and_validate!(content, model, XmlStruct);
|
||||
|
||||
let model = XmlStruct {
|
||||
color: Enum::Strings(vec![String::from("abc"), String::from("def")]),
|
||||
color: Enum::Strings(vec!["abc".to_owned(), "def".to_owned()]),
|
||||
};
|
||||
|
||||
let content = "<base><color><Strings>abc</Strings><Strings>def</Strings></color></base>";
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
#[macro_use]
|
||||
extern crate yaserde_derive;
|
||||
|
||||
use std::io::Read;
|
||||
use yaserde::de::from_str;
|
||||
use yaserde::YaDeserialize;
|
||||
|
||||
fn init() {
|
||||
let _ = env_logger::builder().is_test(true).try_init();
|
||||
@ -24,9 +22,7 @@ fn de_no_content() {
|
||||
let loaded: Result<Book, String> = from_str(content);
|
||||
assert_eq!(
|
||||
loaded,
|
||||
Err(String::from(
|
||||
"Unexpected end of stream: no root element found"
|
||||
))
|
||||
Err("Unexpected end of stream: no root element found".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
@ -45,8 +41,6 @@ fn de_wrong_end_balise() {
|
||||
let loaded: Result<Book, String> = from_str(content);
|
||||
assert_eq!(
|
||||
loaded,
|
||||
Err(String::from(
|
||||
"Unexpected closing tag: book, expected author"
|
||||
))
|
||||
Err("Unexpected closing tag: book, expected author".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
@ -3,10 +3,6 @@ extern crate yaserde;
|
||||
#[macro_use]
|
||||
extern crate yaserde_derive;
|
||||
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use yaserde::{YaDeserialize, YaSerialize};
|
||||
|
||||
fn init() {
|
||||
let _ = env_logger::builder().is_test(true).try_init();
|
||||
}
|
||||
|
||||
@ -3,9 +3,6 @@ extern crate yaserde;
|
||||
#[macro_use]
|
||||
extern crate yaserde_derive;
|
||||
|
||||
use std::io::{Read, Write};
|
||||
use yaserde::{YaDeserialize, YaSerialize};
|
||||
|
||||
fn init() {
|
||||
let _ = env_logger::builder().is_test(true).try_init();
|
||||
}
|
||||
@ -35,8 +32,8 @@ fn struct_simple_namespace() {
|
||||
"#;
|
||||
|
||||
let model = Book {
|
||||
author: String::from("Antoine de Saint-Exupéry"),
|
||||
title: String::from("Little prince"),
|
||||
author: "Antoine de Saint-Exupéry".to_owned(),
|
||||
title: "Little prince".to_owned(),
|
||||
};
|
||||
|
||||
serialize_and_validate!(model, content);
|
||||
@ -69,8 +66,8 @@ fn struct_multiple_namespaces() {
|
||||
"#;
|
||||
|
||||
let model = Book {
|
||||
author: String::from("Antoine de Saint-Exupéry"),
|
||||
title: String::from("Little prince"),
|
||||
author: "Antoine de Saint-Exupéry".to_owned(),
|
||||
title: "Little prince".to_owned(),
|
||||
};
|
||||
|
||||
serialize_and_validate!(model, content);
|
||||
@ -101,8 +98,8 @@ fn struct_partial_namespace() {
|
||||
"#;
|
||||
|
||||
let model = Book {
|
||||
author: String::from("Antoine de Saint-Exupéry"),
|
||||
title: String::from("Little prince"),
|
||||
author: "Antoine de Saint-Exupéry".to_owned(),
|
||||
title: "Little prince".to_owned(),
|
||||
};
|
||||
|
||||
serialize_and_validate!(model, content);
|
||||
@ -135,8 +132,8 @@ fn struct_sub_namespace_definition() {
|
||||
"#;
|
||||
|
||||
let model = Book {
|
||||
author: String::from("Antoine de Saint-Exupéry"),
|
||||
title: String::from("Little prince"),
|
||||
author: "Antoine de Saint-Exupéry".to_owned(),
|
||||
title: "Little prince".to_owned(),
|
||||
};
|
||||
|
||||
// TODO support namespace for attribute to specify local namespace
|
||||
|
||||
@ -3,9 +3,6 @@ extern crate yaserde;
|
||||
#[macro_use]
|
||||
extern crate yaserde_derive;
|
||||
|
||||
use std::io::{Read, Write};
|
||||
use yaserde::{YaDeserialize, YaSerialize};
|
||||
|
||||
fn init() {
|
||||
let _ = env_logger::builder().is_test(true).try_init();
|
||||
}
|
||||
|
||||
@ -177,8 +177,6 @@ fn ser_attributes() {
|
||||
#[test]
|
||||
fn ser_attributes_complex() {
|
||||
mod other_mod {
|
||||
use super::*;
|
||||
|
||||
#[derive(YaSerialize, PartialEq, Debug)]
|
||||
pub enum AttrEnum {
|
||||
#[yaserde(rename = "variant 1")]
|
||||
@ -197,7 +195,7 @@ fn ser_attributes_complex() {
|
||||
#[derive(YaSerialize, PartialEq, Debug)]
|
||||
pub struct Struct {
|
||||
#[yaserde(attribute)]
|
||||
attr_option_string: Option<std::string::String>,
|
||||
attr_option_string: Option<String>,
|
||||
#[yaserde(attribute)]
|
||||
attr_option_enum: Option<other_mod::AttrEnum>,
|
||||
}
|
||||
|
||||
@ -3,9 +3,6 @@ extern crate yaserde;
|
||||
#[macro_use]
|
||||
extern crate yaserde_derive;
|
||||
|
||||
use std::io::Write;
|
||||
use yaserde::YaSerialize;
|
||||
|
||||
fn init() {
|
||||
let _ = env_logger::builder().is_test(true).try_init();
|
||||
}
|
||||
|
||||
@ -3,9 +3,6 @@ extern crate yaserde;
|
||||
#[macro_use]
|
||||
extern crate yaserde_derive;
|
||||
|
||||
use std::io::{Read, Write};
|
||||
use yaserde::{YaDeserialize, YaSerialize};
|
||||
|
||||
fn init() {
|
||||
let _ = env_logger::builder().is_test(true).try_init();
|
||||
}
|
||||
|
||||
@ -18,7 +18,6 @@ proc-macro2 = "~1.0"
|
||||
quote = "~1.0"
|
||||
|
||||
[lib]
|
||||
name = "yaserde_derive"
|
||||
proc-macro = true
|
||||
|
||||
[badges]
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use proc_macro2::{token_stream::IntoIter, Delimiter, Ident, TokenStream, TokenTree};
|
||||
use quote::quote;
|
||||
use std::collections::BTreeMap;
|
||||
use syn::Attribute;
|
||||
|
||||
@ -154,7 +155,8 @@ impl YaSerdeAttribute {
|
||||
match namespace.as_str() {
|
||||
#namespaces_matches
|
||||
bad_namespace => {
|
||||
let msg = format!("bad namespace for {}, found {}", #element_name, bad_namespace);
|
||||
let msg =
|
||||
::std::format!("bad namespace for {}, found {}", #element_name, bad_namespace);
|
||||
return Err(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ use crate::common::attribute::YaSerdeAttribute;
|
||||
use heck::CamelCase;
|
||||
use proc_macro2::Span;
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{format_ident, quote};
|
||||
use std::fmt;
|
||||
use syn::ext::IdentExt;
|
||||
use syn::spanned::Spanned;
|
||||
@ -184,9 +185,8 @@ pub enum Field {
|
||||
}
|
||||
|
||||
impl Field {
|
||||
pub fn get_simple_type_visitor(&self) -> TokenStream {
|
||||
let ident = format_ident!("visit_{}", self.to_string());
|
||||
quote! {#ident}
|
||||
pub fn get_simple_type_visitor(&self) -> Ident {
|
||||
format_ident!("visit_{}", self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,25 +255,25 @@ impl From<&syn::PathSegment> for Field {
|
||||
impl Into<proc_macro2::TokenStream> for Field {
|
||||
fn into(self) -> proc_macro2::TokenStream {
|
||||
match self {
|
||||
Field::FieldString => quote! {std::string::String},
|
||||
Field::FieldBool => quote! {bool},
|
||||
Field::FieldI8 => quote! {i8},
|
||||
Field::FieldU8 => quote! {u8},
|
||||
Field::FieldI16 => quote! {i16},
|
||||
Field::FieldU16 => quote! {u16},
|
||||
Field::FieldI32 => quote! {i32},
|
||||
Field::FieldU32 => quote! {u32},
|
||||
Field::FieldI64 => quote! {i64},
|
||||
Field::FieldU64 => quote! {u64},
|
||||
Field::FieldF32 => quote! {f32},
|
||||
Field::FieldF64 => quote! {f64},
|
||||
Field::FieldString => quote! { ::std::string::String },
|
||||
Field::FieldBool => quote! { bool },
|
||||
Field::FieldI8 => quote! { i8 },
|
||||
Field::FieldU8 => quote! { u8 },
|
||||
Field::FieldI16 => quote! { i16 },
|
||||
Field::FieldU16 => quote! { u16 },
|
||||
Field::FieldI32 => quote! { i32 },
|
||||
Field::FieldU32 => quote! { u32 },
|
||||
Field::FieldI64 => quote! { i64 },
|
||||
Field::FieldU64 => quote! { u64 },
|
||||
Field::FieldF32 => quote! { f32 },
|
||||
Field::FieldF64 => quote! { f64 },
|
||||
_ => panic!("Not a simple type: {:?}", self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for &Field {
|
||||
fn into(self) -> std::string::String {
|
||||
fn into(self) -> String {
|
||||
match self {
|
||||
Field::FieldString => "str".to_string(),
|
||||
Field::FieldBool => "bool".to_string(),
|
||||
@ -294,7 +294,7 @@ impl Into<String> for &Field {
|
||||
|
||||
impl fmt::Display for Field {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let string_representation: std::string::String = self.into();
|
||||
let string_representation: String = self.into();
|
||||
write!(f, "{}", string_representation)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use crate::common::YaSerdeField;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
pub fn build_default_value(
|
||||
field: &YaSerdeField,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use crate::common::{Field, YaSerdeAttribute, YaSerdeField};
|
||||
use proc_macro2::TokenStream;
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::{DataEnum, Fields, Ident};
|
||||
|
||||
pub fn parse(
|
||||
@ -25,35 +26,31 @@ pub fn parse(
|
||||
let flatten = root_attributes.flatten;
|
||||
|
||||
quote! {
|
||||
use xml::reader::XmlEvent;
|
||||
use yaserde::Visitor;
|
||||
#[allow(unknown_lints, unused_imports)]
|
||||
use std::str::FromStr;
|
||||
use log::{debug, trace};
|
||||
|
||||
impl YaDeserialize for #name {
|
||||
impl ::yaserde::YaDeserialize for #name {
|
||||
#[allow(unused_variables)]
|
||||
fn deserialize<R: Read>(reader: &mut yaserde::de::Deserializer<R>) -> Result<Self, std::string::String> {
|
||||
fn deserialize<R: ::std::io::Read>(
|
||||
reader: &mut ::yaserde::de::Deserializer<R>,
|
||||
) -> ::std::result::Result<Self, ::std::string::String> {
|
||||
let (named_element, enum_namespace) =
|
||||
if let XmlEvent::StartElement{name, ..} = reader.peek()?.to_owned() {
|
||||
if let ::xml::reader::XmlEvent::StartElement{ name, .. } = reader.peek()?.to_owned() {
|
||||
(name.local_name.to_owned(), name.namespace.clone())
|
||||
} else {
|
||||
(std::string::String::from(#root), None)
|
||||
(::std::string::String::from(#root), ::std::option::Option::None)
|
||||
};
|
||||
|
||||
let start_depth = reader.depth();
|
||||
debug!("Enum {} @ {}: start to parse {:?}", stringify!(#name), start_depth, named_element);
|
||||
::log::debug!("Enum {} @ {}: start to parse {:?}", stringify!(#name), start_depth, named_element);
|
||||
|
||||
#namespaces_matching
|
||||
|
||||
#[allow(unused_assignments, unused_mut)]
|
||||
let mut enum_value = None;
|
||||
let mut enum_value = ::std::option::Option::None;
|
||||
|
||||
loop {
|
||||
let event = reader.peek()?.to_owned();
|
||||
trace!("Enum {} @ {}: matching {:?}", stringify!(#name), start_depth, event);
|
||||
::log::trace!("Enum {} @ {}: matching {:?}", stringify!(#name), start_depth, event);
|
||||
match event {
|
||||
XmlEvent::StartElement{ref name, ref attributes, ..} => {
|
||||
::xml::reader::XmlEvent::StartElement { ref name, ref attributes, .. } => {
|
||||
match name.local_name.as_str() {
|
||||
#match_to_enum
|
||||
_named_element => {
|
||||
@ -61,40 +58,42 @@ pub fn parse(
|
||||
}
|
||||
}
|
||||
|
||||
if let XmlEvent::Characters(content) = reader.peek()?.to_owned() {
|
||||
if let ::xml::reader::XmlEvent::Characters(content) = reader.peek()?.to_owned() {
|
||||
match content.as_str() {
|
||||
#match_to_enum
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
XmlEvent::EndElement{ref name} => {
|
||||
::xml::reader::XmlEvent::EndElement { ref name } => {
|
||||
if name.local_name == named_element {
|
||||
break;
|
||||
}
|
||||
let _root = reader.next_event();
|
||||
}
|
||||
XmlEvent::Characters(ref text_content) => {
|
||||
::xml::reader::XmlEvent::Characters(ref text_content) => {
|
||||
let _root = reader.next_event();
|
||||
}
|
||||
XmlEvent::EndDocument => {
|
||||
::xml::reader::XmlEvent::EndDocument => {
|
||||
if #flatten {
|
||||
break;
|
||||
}
|
||||
|
||||
return Err(format!("End of document, missing some content ?"))
|
||||
return ::std::result::Result::Err(
|
||||
::std::format!("End of document, missing some content ?"),
|
||||
);
|
||||
}
|
||||
event => {
|
||||
return Err(format!("unknown event {:?}", event))
|
||||
return ::std::result::Result::Err(::std::format!("unknown event {:?}", event))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug!("Enum {} @ {}: success", stringify!(#name), start_depth);
|
||||
::log::debug!("Enum {} @ {}: success", stringify!(#name), start_depth);
|
||||
match enum_value {
|
||||
Some(value) => Ok(value),
|
||||
None => {
|
||||
Ok(#name::default())
|
||||
::std::option::Option::Some(value) => ::std::result::Result::Ok(value),
|
||||
::std::option::Option::None => {
|
||||
::std::result::Result::Ok(<#name as ::std::default::Default>::default())
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -113,7 +112,7 @@ fn parse_variant(variant: &syn::Variant, name: &Ident) -> Option<TokenStream> {
|
||||
match variant.fields {
|
||||
Fields::Unit => Some(quote! {
|
||||
#xml_element_name => {
|
||||
enum_value = Some(#variant_name);
|
||||
enum_value = ::std::option::Option::Some(#variant_name);
|
||||
}
|
||||
}),
|
||||
Fields::Unnamed(ref fields) => {
|
||||
@ -150,23 +149,25 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
|
||||
.iter()
|
||||
.map(|field| YaSerdeField::new(field.clone()))
|
||||
.enumerate()
|
||||
.map(|(idx, field)| {
|
||||
.filter_map(|(idx, field)| {
|
||||
let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.get_span());
|
||||
|
||||
let make_visitor =
|
||||
|visitor: &TokenStream, field_type: &TokenStream, fn_body: &TokenStream| {
|
||||
Some(quote! {
|
||||
#[allow(non_snake_case, non_camel_case_types)]
|
||||
struct #visitor_label;
|
||||
impl<'de> Visitor<'de> for #visitor_label {
|
||||
type Value = #field_type;
|
||||
let make_visitor = |visitor: &Ident, field_type: &TokenStream, fn_body: &TokenStream| {
|
||||
quote! {
|
||||
#[allow(non_snake_case, non_camel_case_types)]
|
||||
struct #visitor_label;
|
||||
impl<'de> ::yaserde::Visitor<'de> for #visitor_label {
|
||||
type Value = #field_type;
|
||||
|
||||
fn #visitor(self, v: &str) -> Result<Self::Value, std::string::String> {
|
||||
#fn_body
|
||||
}
|
||||
fn #visitor(
|
||||
self,
|
||||
v: &str,
|
||||
) -> ::std::result::Result<Self::Value, ::std::string::String> {
|
||||
#fn_body
|
||||
}
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let simple_type_visitor = |simple_type: Field| {
|
||||
let visitor = simple_type.get_simple_type_visitor();
|
||||
@ -175,36 +176,36 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
|
||||
make_visitor(
|
||||
&visitor,
|
||||
&field_type,
|
||||
"e! { Ok(#field_type::from_str(v).unwrap()) },
|
||||
"e! { ::std::result::Result::Ok(#field_type::from_str(v).unwrap()) },
|
||||
)
|
||||
};
|
||||
|
||||
match field.get_type() {
|
||||
Field::FieldStruct { struct_name } => {
|
||||
let struct_id: std::string::String = struct_name
|
||||
let struct_id: String = struct_name
|
||||
.segments
|
||||
.iter()
|
||||
.map(|s| s.ident.to_string())
|
||||
.collect();
|
||||
|
||||
make_visitor(
|
||||
"e! { visit_str },
|
||||
Some(make_visitor(
|
||||
&Ident::new("visit_str", Span::call_site()),
|
||||
"e! { #struct_name },
|
||||
"e! {
|
||||
let content = "<".to_string() + #struct_id + ">" + v + "</" + #struct_id + ">";
|
||||
let value : Result<#struct_name, std::string::String> = yaserde::de::from_str(&content);
|
||||
let value: ::std::result::Result<#struct_name, ::std::string::String> =
|
||||
::yaserde::de::from_str(&content);
|
||||
value
|
||||
},
|
||||
)
|
||||
))
|
||||
}
|
||||
Field::FieldOption { data_type } | Field::FieldVec { data_type } => match *data_type {
|
||||
Field::FieldStruct { .. } => None,
|
||||
simple_type => simple_type_visitor(simple_type),
|
||||
simple_type => Some(simple_type_visitor(simple_type)),
|
||||
},
|
||||
simple_type => simple_type_visitor(simple_type),
|
||||
simple_type => Some(simple_type_visitor(simple_type)),
|
||||
}
|
||||
})
|
||||
.filter_map(|f| f)
|
||||
.collect()
|
||||
}
|
||||
|
||||
@ -230,18 +231,22 @@ fn build_unnamed_visitor_calls(
|
||||
let visitor = #visitor_label{};
|
||||
|
||||
let result = reader.read_inner_value::<#field_type, _>(|reader| {
|
||||
if let XmlEvent::EndElement { .. } = *reader.peek()? {
|
||||
if let ::xml::reader::XmlEvent::EndElement { .. } = *reader.peek()? {
|
||||
return visitor.#visitor("");
|
||||
}
|
||||
|
||||
if let Ok(XmlEvent::Characters(s)) = reader.next_event() {
|
||||
if let ::std::result::Result::Ok(::xml::reader::XmlEvent::Characters(s))
|
||||
= reader.next_event()
|
||||
{
|
||||
visitor.#visitor(&s)
|
||||
} else {
|
||||
Err(format!("unable to parse content for {}", #label_name))
|
||||
::std::result::Result::Err(
|
||||
::std::format!("unable to parse content for {}", #label_name),
|
||||
)
|
||||
}
|
||||
});
|
||||
|
||||
if let Ok(value) = result {
|
||||
if let ::std::result::Result::Ok(value) = result {
|
||||
#action
|
||||
}
|
||||
})
|
||||
@ -261,16 +266,24 @@ fn build_unnamed_visitor_calls(
|
||||
})
|
||||
};
|
||||
|
||||
let set_val = quote! { enum_value = Some(#variant_name(value)) };
|
||||
let set_opt = quote! { enum_value = Some(#variant_name(Some(value))) };
|
||||
let set_val = quote! {
|
||||
enum_value = ::std::option::Option::Some(#variant_name(value))
|
||||
};
|
||||
let set_opt = quote! {
|
||||
enum_value = ::std::option::Option::Some(#variant_name(::std::option::Option::Some(value)))
|
||||
};
|
||||
let set_vec = quote! {
|
||||
match enum_value {
|
||||
Some(ref mut v) => match v {
|
||||
#variant_name(ref mut v) => v.push(value),
|
||||
_ => return Err(std::string::String::from("Got sequence of different types"))
|
||||
_ => {
|
||||
return ::std::result::Result::Err(
|
||||
::std::string::String::from("Got sequence of different types"),
|
||||
);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
enum_value = Some(#variant_name(vec![value]));
|
||||
enum_value = ::std::option::Option::Some(#variant_name(vec![value]));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -2,6 +2,7 @@ use crate::common::{Field, YaSerdeAttribute, YaSerdeField};
|
||||
use crate::de::build_default_value::build_default_value;
|
||||
use heck::CamelCase;
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::{DataStruct, Ident};
|
||||
|
||||
pub fn parse(
|
||||
@ -25,25 +26,33 @@ pub fn parse(
|
||||
Field::FieldStruct { struct_name } => build_default_value(
|
||||
&field,
|
||||
Some(quote!(#struct_name)),
|
||||
quote!(#struct_name::default()),
|
||||
quote!(<#struct_name as ::std::default::Default>::default()),
|
||||
),
|
||||
Field::FieldOption { .. } => build_default_value(&field, None, quote!(None)),
|
||||
Field::FieldOption { .. } => {
|
||||
build_default_value(&field, None, quote!(::std::option::Option::None))
|
||||
}
|
||||
Field::FieldVec { data_type } => match *data_type {
|
||||
Field::FieldStruct { ref struct_name } => {
|
||||
build_default_value(&field, Some(quote!(Vec<#struct_name>)), quote!(vec![]))
|
||||
}
|
||||
Field::FieldStruct { ref struct_name } => build_default_value(
|
||||
&field,
|
||||
Some(quote!(::std::vec::Vec<#struct_name>)),
|
||||
quote!(::std::vec![]),
|
||||
),
|
||||
Field::FieldOption { .. } | Field::FieldVec { .. } => {
|
||||
unimplemented!();
|
||||
}
|
||||
simple_type => {
|
||||
let type_token: TokenStream = simple_type.into();
|
||||
|
||||
build_default_value(&field, Some(quote!(Vec<#type_token>)), quote!(vec![]))
|
||||
build_default_value(
|
||||
&field,
|
||||
Some(quote!(::std::vec::Vec<#type_token>)),
|
||||
quote!(::std::vec![]),
|
||||
)
|
||||
}
|
||||
},
|
||||
simple_type => {
|
||||
let type_token: TokenStream = simple_type.into();
|
||||
let value_builder = quote!(#type_token::default());
|
||||
let value_builder = quote!(<#type_token as ::std::default::Default>::default());
|
||||
|
||||
build_default_value(&field, Some(type_token), value_builder)
|
||||
}
|
||||
@ -57,7 +66,7 @@ pub fn parse(
|
||||
.map(|field| YaSerdeField::new(field.clone()))
|
||||
.map(|field| {
|
||||
let struct_visitor = |struct_name: syn::Path| {
|
||||
let struct_id: std::string::String = struct_name
|
||||
let struct_id: String = struct_name
|
||||
.segments
|
||||
.iter()
|
||||
.map(|s| s.ident.to_string())
|
||||
@ -68,13 +77,15 @@ pub fn parse(
|
||||
Some(quote! {
|
||||
#[allow(non_snake_case, non_camel_case_types)]
|
||||
struct #visitor_label;
|
||||
impl<'de> Visitor<'de> for #visitor_label {
|
||||
impl<'de> ::yaserde::Visitor<'de> for #visitor_label {
|
||||
type Value = #struct_name;
|
||||
|
||||
fn visit_str(self, v: &str) -> Result<Self::Value, std::string::String> {
|
||||
fn visit_str(
|
||||
self,
|
||||
v: &str,
|
||||
) -> ::std::result::Result<Self::Value, ::std::string::String> {
|
||||
let content = "<".to_string() + #struct_id + ">" + v + "</" + #struct_id + ">";
|
||||
let value : Result<#struct_name, std::string::String> = yaserde::de::from_str(&content);
|
||||
value
|
||||
::yaserde::de::from_str(&content)
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -85,27 +96,27 @@ pub fn parse(
|
||||
let visitor_label = field.get_visitor_ident(None);
|
||||
let field_type: TokenStream = simple_type.into();
|
||||
|
||||
let map_if_bool =
|
||||
if format!("{}", field_type) == "bool" {
|
||||
quote!(
|
||||
match v {
|
||||
"1" => "true",
|
||||
"0" => "false",
|
||||
_ => v,
|
||||
}
|
||||
)
|
||||
} else {
|
||||
quote!(v)
|
||||
};
|
||||
let map_if_bool = if field_type.to_string() == "bool" {
|
||||
quote!(match v {
|
||||
"1" => "true",
|
||||
"0" => "false",
|
||||
_ => v,
|
||||
})
|
||||
} else {
|
||||
quote!(v)
|
||||
};
|
||||
|
||||
Some(quote! {
|
||||
#[allow(non_snake_case, non_camel_case_types)]
|
||||
struct #visitor_label;
|
||||
impl<'de> Visitor<'de> for #visitor_label {
|
||||
impl<'de> ::yaserde::Visitor<'de> for #visitor_label {
|
||||
type Value = #field_type;
|
||||
|
||||
fn #visitor(self, v: &str) -> Result<Self::Value, std::string::String> {
|
||||
Ok(#field_type::from_str(#map_if_bool).unwrap())
|
||||
fn #visitor(
|
||||
self,
|
||||
v: &str,
|
||||
) -> ::std::result::Result<Self::Value, ::std::string::String> {
|
||||
::std::result::Result::Ok(#field_type::from_str(#map_if_bool).unwrap())
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -145,7 +156,7 @@ pub fn parse(
|
||||
// Don't count current struct's StartElement as substruct's StartElement
|
||||
let _root = reader.next_event();
|
||||
}
|
||||
if let Ok(XmlEvent::StartElement { .. }) = reader.peek() {
|
||||
if let Ok(::xml::reader::XmlEvent::StartElement { .. }) = reader.peek() {
|
||||
// If substruct's start element found then deserialize substruct
|
||||
let value = #struct_name::deserialize(reader)?;
|
||||
#value_label #action;
|
||||
@ -173,10 +184,12 @@ pub fn parse(
|
||||
};
|
||||
|
||||
match field.get_type() {
|
||||
Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! {= value}),
|
||||
Field::FieldOption { data_type } => visit_sub(data_type, quote! {= Some(value)}),
|
||||
Field::FieldVec { data_type } => visit_sub(data_type, quote! {.push(value)}),
|
||||
simple_type => visit_simple(simple_type, quote! {= value}),
|
||||
Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! { = value }),
|
||||
Field::FieldOption { data_type } => {
|
||||
visit_sub(data_type, quote! { = ::std::option::Option::Some(value) })
|
||||
}
|
||||
Field::FieldVec { data_type } => visit_sub(data_type, quote! { .push(value) }),
|
||||
simple_type => visit_simple(simple_type, quote! { = value }),
|
||||
}
|
||||
})
|
||||
.filter_map(|x| x)
|
||||
@ -192,11 +205,11 @@ pub fn parse(
|
||||
|
||||
match field.get_type() {
|
||||
Field::FieldStruct { .. } => Some(quote! {
|
||||
#value_label = yaserde::de::from_str(&unused_xml_elements)?;
|
||||
#value_label = ::yaserde::de::from_str(&unused_xml_elements)?;
|
||||
}),
|
||||
Field::FieldOption { data_type } => match *data_type {
|
||||
Field::FieldStruct { .. } => Some(quote! {
|
||||
#value_label = yaserde::de::from_str(&unused_xml_elements).ok();
|
||||
#value_label = ::yaserde::de::from_str(&unused_xml_elements).ok();
|
||||
}),
|
||||
field_type => unimplemented!(r#""flatten" is not implemented for {:?}"#, field_type),
|
||||
},
|
||||
@ -216,7 +229,7 @@ pub fn parse(
|
||||
let label_name = field.renamed_label_without_namespace();
|
||||
let visitor_label = build_visitor_ident(&label_name, field.get_span(), None);
|
||||
|
||||
let visit = |action: &TokenStream, visitor: &TokenStream, visitor_label: &Ident| {
|
||||
let visit = |action: &TokenStream, visitor: &Ident, visitor_label: &Ident| {
|
||||
Some(quote! {
|
||||
for attr in attributes {
|
||||
if attr.name.local_name == #label_name {
|
||||
@ -241,7 +254,7 @@ pub fn parse(
|
||||
let visit_struct = |struct_name: syn::Path, action: TokenStream| {
|
||||
visit(
|
||||
&action,
|
||||
"e! {visit_str},
|
||||
&Ident::new("visit_str", Span::call_site()),
|
||||
&build_visitor_ident(&label_name, field.get_span(), Some(&struct_name)),
|
||||
)
|
||||
};
|
||||
@ -262,10 +275,12 @@ pub fn parse(
|
||||
|
||||
match field.get_type() {
|
||||
Field::FieldString => visit_string(),
|
||||
Field::FieldOption { data_type } => visit_sub(data_type, quote! {= Some(value)}),
|
||||
Field::FieldOption { data_type } => {
|
||||
visit_sub(data_type, quote! { = ::std::option::Option::Some(value) })
|
||||
}
|
||||
Field::FieldVec { .. } => unimplemented!(),
|
||||
Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! {= value}),
|
||||
simple_type => visit_simple(simple_type, quote! {= value}),
|
||||
Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! { = value }),
|
||||
simple_type => visit_simple(simple_type, quote! { = value }),
|
||||
}
|
||||
})
|
||||
.filter_map(|x| x)
|
||||
@ -280,18 +295,18 @@ pub fn parse(
|
||||
|
||||
let set_text = |action: &TokenStream| {
|
||||
if field.is_text_content() {
|
||||
Some(quote! {#label = #action;})
|
||||
Some(quote! { #label = #action; })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
match field.get_type() {
|
||||
Field::FieldString => set_text("e! {text_content.to_owned()}),
|
||||
Field::FieldString => set_text("e! { text_content.to_owned() }),
|
||||
Field::FieldStruct { .. } | Field::FieldOption { .. } | Field::FieldVec { .. } => None,
|
||||
simple_type => {
|
||||
let type_token: TokenStream = simple_type.into();
|
||||
set_text("e! {#type_token::from_str(text_content).unwrap()})
|
||||
set_text("e! { #type_token::from_str(text_content).unwrap() })
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -319,24 +334,19 @@ pub fn parse(
|
||||
let flatten = root_attributes.flatten;
|
||||
|
||||
quote! {
|
||||
use xml::reader::{XmlEvent, EventReader};
|
||||
use xml::writer::EventWriter;
|
||||
use yaserde::Visitor;
|
||||
#[allow(unknown_lints, unused_imports)]
|
||||
use std::str::FromStr;
|
||||
use log::{debug, trace};
|
||||
|
||||
impl YaDeserialize for #name {
|
||||
impl ::yaserde::YaDeserialize for #name {
|
||||
#[allow(unused_variables)]
|
||||
fn deserialize<R: Read>(reader: &mut yaserde::de::Deserializer<R>) -> Result<Self, std::string::String> {
|
||||
fn deserialize<R: ::std::io::Read>(
|
||||
reader: &mut ::yaserde::de::Deserializer<R>,
|
||||
) -> ::std::result::Result<Self, ::std::string::String> {
|
||||
let (named_element, struct_namespace) =
|
||||
if let XmlEvent::StartElement{name, ..} = reader.peek()?.to_owned() {
|
||||
if let ::xml::reader::XmlEvent::StartElement { name, .. } = reader.peek()?.to_owned() {
|
||||
(name.local_name.to_owned(), name.namespace.clone())
|
||||
} else {
|
||||
(std::string::String::from(#root), None)
|
||||
(::std::string::String::from(#root), ::std::option::Option::None)
|
||||
};
|
||||
let start_depth = reader.depth();
|
||||
debug!("Struct {} @ {}: start to parse {:?}", stringify!(#name), start_depth,
|
||||
::log::debug!("Struct {} @ {}: start to parse {:?}", stringify!(#name), start_depth,
|
||||
named_element);
|
||||
|
||||
if reader.depth() == 0 {
|
||||
@ -351,9 +361,12 @@ pub fn parse(
|
||||
|
||||
loop {
|
||||
let event = reader.peek()?.to_owned();
|
||||
trace!("Struct {} @ {}: matching {:?}", stringify!(#name), start_depth, event);
|
||||
::log::trace!(
|
||||
"Struct {} @ {}: matching {:?}",
|
||||
stringify!(#name), start_depth, event,
|
||||
);
|
||||
match event {
|
||||
XmlEvent::StartElement{ref name, ref attributes, ..} => {
|
||||
::xml::reader::XmlEvent::StartElement{ref name, ref attributes, ..} => {
|
||||
match name.local_name.as_str() {
|
||||
#call_visitors
|
||||
_ => {
|
||||
@ -372,7 +385,7 @@ pub fn parse(
|
||||
}
|
||||
depth += 1;
|
||||
}
|
||||
XmlEvent::EndElement{ref name} => {
|
||||
::xml::reader::XmlEvent::EndElement { ref name } => {
|
||||
if name.local_name == named_element {
|
||||
#write_unused
|
||||
break;
|
||||
@ -381,26 +394,26 @@ pub fn parse(
|
||||
#write_unused
|
||||
depth -= 1;
|
||||
}
|
||||
XmlEvent::EndDocument => {
|
||||
::xml::reader::XmlEvent::EndDocument => {
|
||||
if #flatten {
|
||||
break;
|
||||
}
|
||||
}
|
||||
XmlEvent::Characters(ref text_content) => {
|
||||
::xml::reader::XmlEvent::Characters(ref text_content) => {
|
||||
#set_text
|
||||
let event = reader.next_event()?;
|
||||
#write_unused
|
||||
}
|
||||
event => {
|
||||
return Err(format!("unknown event {:?}", event))
|
||||
return ::std::result::Result::Err(::std::format!("unknown event {:?}", event));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#visit_unused
|
||||
|
||||
debug!("Struct {} @ {}: success", stringify!(#name), start_depth);
|
||||
Ok(#name{#struct_builder})
|
||||
::log::debug!("Struct {} @ {}: success", stringify!(#name), start_depth);
|
||||
::std::result::Result::Ok(#name{#struct_builder})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -408,7 +421,7 @@ pub fn parse(
|
||||
|
||||
fn build_call_visitor(
|
||||
field_type: &TokenStream,
|
||||
visitor: &TokenStream,
|
||||
visitor: &Ident,
|
||||
action: &TokenStream,
|
||||
field: &YaSerdeField,
|
||||
root_attributes: &YaSerdeAttribute,
|
||||
@ -430,16 +443,16 @@ fn build_call_visitor(
|
||||
#namespaces_matching
|
||||
|
||||
let result = reader.read_inner_value::<#field_type, _>(|reader| {
|
||||
if let Ok(XmlEvent::Characters(s)) = reader.peek() {
|
||||
if let ::std::result::Result::Ok(::xml::reader::XmlEvent::Characters(s)) = reader.peek() {
|
||||
let val = visitor.#visitor(&s);
|
||||
let _event = reader.next_event()?;
|
||||
val
|
||||
} else {
|
||||
Err(format!("unable to parse content for {}", #label_name))
|
||||
::std::result::Result::Err(::std::format!("unable to parse content for {}", #label_name))
|
||||
}
|
||||
});
|
||||
|
||||
if let Ok(value) = result {
|
||||
if let ::std::result::Result::Ok(value) = result {
|
||||
#value_label#action
|
||||
}
|
||||
}
|
||||
@ -477,19 +490,19 @@ fn build_code_for_unused_xml_events(
|
||||
) {
|
||||
(
|
||||
Some(quote! {
|
||||
let mut buf = Vec::new();
|
||||
let mut writer = Some(EventWriter::new(&mut buf));
|
||||
let mut buf = ::std::vec![];
|
||||
let mut writer = ::std::option::Option::Some(::xml::writer::EventWriter::new(&mut buf));
|
||||
}),
|
||||
Some(quote! {
|
||||
if let Some(ref mut w) = writer {
|
||||
if let ::std::option::Option::Some(ref mut w) = writer {
|
||||
if w.write(event.as_writer_event().unwrap()).is_err() {
|
||||
writer = None;
|
||||
writer = ::std::option::Option::None;
|
||||
}
|
||||
}
|
||||
}),
|
||||
Some(quote! {
|
||||
if writer.is_some() {
|
||||
let unused_xml_elements = std::string::String::from_utf8(buf).unwrap();
|
||||
let unused_xml_elements = ::std::string::String::from_utf8(buf).unwrap();
|
||||
#call_flatten_visitors
|
||||
}
|
||||
}),
|
||||
|
||||
@ -3,8 +3,8 @@ pub mod expand_enum;
|
||||
pub mod expand_struct;
|
||||
|
||||
use crate::common::YaSerdeAttribute;
|
||||
use proc_macro2::TokenStream;
|
||||
use syn::Ident;
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::quote;
|
||||
|
||||
pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result<TokenStream, String> {
|
||||
let name = &ast.ident;
|
||||
@ -31,13 +31,13 @@ pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result<TokenStream,
|
||||
|
||||
let dummy_const = Ident::new(&format!("_IMPL_YA_DESERIALIZE_FOR_{}", name), name.span());
|
||||
|
||||
let generated = quote! {
|
||||
Ok(quote! {
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const #dummy_const: () = {
|
||||
extern crate yaserde as _yaserde;
|
||||
use ::std::str::FromStr as _;
|
||||
use ::yaserde::Visitor as _;
|
||||
|
||||
#impl_block
|
||||
};
|
||||
};
|
||||
|
||||
Ok(generated)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,10 +1,7 @@
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
// Required for Rust < 1.42
|
||||
extern crate proc_macro;
|
||||
extern crate proc_macro2;
|
||||
#[macro_use]
|
||||
extern crate quote;
|
||||
extern crate syn;
|
||||
|
||||
mod common;
|
||||
mod de;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use crate::common::YaSerdeField;
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::quote;
|
||||
|
||||
pub fn enclose_formatted_characters(label: &Ident, label_name: String) -> TokenStream {
|
||||
enclose_xml_event(label_name, quote!(format!("{}", &self.#label)))
|
||||
@ -15,14 +16,14 @@ pub fn enclose_characters(label: &Option<Ident>, label_name: String) -> TokenStr
|
||||
|
||||
fn enclose_xml_event(label_name: String, yaserde_format: TokenStream) -> TokenStream {
|
||||
quote! {
|
||||
let start_event = XmlEvent::start_element(#label_name);
|
||||
let start_event = ::xml::writer::XmlEvent::start_element(#label_name);
|
||||
writer.write(start_event).map_err(|e| e.to_string())?;
|
||||
|
||||
let yaserde_value = #yaserde_format;
|
||||
let data_event = XmlEvent::characters(&yaserde_value);
|
||||
let data_event = ::xml::writer::XmlEvent::characters(&yaserde_value);
|
||||
writer.write(data_event).map_err(|e| e.to_string())?;
|
||||
|
||||
let end_event = XmlEvent::end_element();
|
||||
let end_event = ::xml::writer::XmlEvent::end_element();
|
||||
writer.write(end_event).map_err(|e| e.to_string())?;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use crate::common::{Field, YaSerdeAttribute, YaSerdeField};
|
||||
use crate::ser::{implement_serializer::implement_serializer, label::build_label_name};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::DataEnum;
|
||||
use syn::Fields;
|
||||
use syn::Ident;
|
||||
@ -41,7 +42,7 @@ fn inner_enum_inspector(
|
||||
match variant.fields {
|
||||
Fields::Unit => Some(quote! {
|
||||
&#name::#label => {
|
||||
let data_event = XmlEvent::characters(#label_name);
|
||||
let data_event = ::xml::writer::XmlEvent::characters(#label_name);
|
||||
writer.write(data_event).map_err(|e| e.to_string())?;
|
||||
}
|
||||
}),
|
||||
@ -56,7 +57,7 @@ fn inner_enum_inspector(
|
||||
|
||||
if field.is_text_content() {
|
||||
return Some(quote!(
|
||||
let data_event = XmlEvent::characters(&self.#field_label);
|
||||
let data_event = ::xml::writer::XmlEvent::characters(&self.#field_label);
|
||||
writer.write(data_event).map_err(|e| e.to_string())?;
|
||||
));
|
||||
}
|
||||
@ -78,15 +79,16 @@ fn inner_enum_inspector(
|
||||
| Field::FieldF64 => Some({
|
||||
quote! {
|
||||
match self {
|
||||
&#name::#label{ref #field_label, ..} => {
|
||||
let struct_start_event = XmlEvent::start_element(#field_label_name);
|
||||
&#name::#label { ref #field_label, .. } => {
|
||||
let struct_start_event =
|
||||
::xml::writer::XmlEvent::start_element(#field_label_name);
|
||||
writer.write(struct_start_event).map_err(|e| e.to_string())?;
|
||||
|
||||
let string_value = #field_label.to_string();
|
||||
let data_event = XmlEvent::characters(&string_value);
|
||||
let data_event = ::xml::writer::XmlEvent::characters(&string_value);
|
||||
writer.write(data_event).map_err(|e| e.to_string())?;
|
||||
|
||||
let struct_end_event = XmlEvent::end_element();
|
||||
let struct_end_event = ::xml::writer::XmlEvent::end_element();
|
||||
writer.write(struct_end_event).map_err(|e| e.to_string())?;
|
||||
},
|
||||
_ => {},
|
||||
@ -96,7 +98,9 @@ fn inner_enum_inspector(
|
||||
Field::FieldStruct { .. } => Some(quote! {
|
||||
match self {
|
||||
&#name::#label{ref #field_label, ..} => {
|
||||
writer.set_start_event_name(Some(#field_label_name.to_string()));
|
||||
writer.set_start_event_name(
|
||||
::std::option::Option::Some(#field_label_name.to_string()),
|
||||
);
|
||||
writer.set_skip_start_end(false);
|
||||
#field_label.serialize(writer)?;
|
||||
},
|
||||
@ -105,9 +109,11 @@ fn inner_enum_inspector(
|
||||
}),
|
||||
Field::FieldVec { .. } => Some(quote! {
|
||||
match self {
|
||||
&#name::#label{ref #field_label, ..} => {
|
||||
&#name::#label { ref #field_label, .. } => {
|
||||
for item in #field_label {
|
||||
writer.set_start_event_name(Some(#field_label_name.to_string()));
|
||||
writer.set_start_event_name(
|
||||
::std::option::Option::Some(#field_label_name.to_string()),
|
||||
);
|
||||
writer.set_skip_start_end(false);
|
||||
item.serialize(writer)?;
|
||||
}
|
||||
@ -136,29 +142,29 @@ fn inner_enum_inspector(
|
||||
.map(|field| {
|
||||
let write_element = |action: &TokenStream| {
|
||||
quote! {
|
||||
let struct_start_event = XmlEvent::start_element(#label_name);
|
||||
let struct_start_event = ::xml::writer::XmlEvent::start_element(#label_name);
|
||||
writer.write(struct_start_event).map_err(|e| e.to_string())?;
|
||||
|
||||
#action
|
||||
|
||||
let struct_end_event = XmlEvent::end_element();
|
||||
let struct_end_event = ::xml::writer::XmlEvent::end_element();
|
||||
writer.write(struct_end_event).map_err(|e| e.to_string())?;
|
||||
}
|
||||
};
|
||||
|
||||
let write_string_chars = quote! {
|
||||
let data_event = XmlEvent::characters(item);
|
||||
let data_event = ::xml::writer::XmlEvent::characters(item);
|
||||
writer.write(data_event).map_err(|e| e.to_string())?;
|
||||
};
|
||||
|
||||
let write_simple_type = write_element("e! {
|
||||
let s = item.to_string();
|
||||
let data_event = XmlEvent::characters(&s);
|
||||
let data_event = ::xml::writer::XmlEvent::characters(&s);
|
||||
writer.write(data_event).map_err(|e| e.to_string())?;
|
||||
});
|
||||
|
||||
let serialize = quote! {
|
||||
writer.set_start_event_name(None);
|
||||
writer.set_start_event_name(::std::option::Option::None);
|
||||
writer.set_skip_start_end(true);
|
||||
item.serialize(writer)?;
|
||||
};
|
||||
@ -186,7 +192,7 @@ fn inner_enum_inspector(
|
||||
let write = write_sub_type(*data_type);
|
||||
|
||||
Some(match_field("e! {
|
||||
if let Some(item) = item {
|
||||
if let ::std::option::Option::Some(item) = item {
|
||||
#write
|
||||
}
|
||||
}))
|
||||
|
||||
@ -2,6 +2,7 @@ use crate::common::{Field, YaSerdeAttribute, YaSerdeField};
|
||||
|
||||
use crate::ser::{element::*, implement_serializer::implement_serializer};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::DataStruct;
|
||||
use syn::Ident;
|
||||
|
||||
@ -44,7 +45,7 @@ pub fn serialize(
|
||||
Field::FieldString => field.ser_wrap_default_attribute(
|
||||
None,
|
||||
quote!({
|
||||
if let Some(ref value) = self.#label {
|
||||
if let ::std::option::Option::Some(ref value) = self.#label {
|
||||
struct_start_event.attr(#label_name, value)
|
||||
} else {
|
||||
struct_start_event
|
||||
@ -62,9 +63,11 @@ pub fn serialize(
|
||||
| Field::FieldU64
|
||||
| Field::FieldF32
|
||||
| Field::FieldF64 => field.ser_wrap_default_attribute(
|
||||
Some(quote!(self.#label.map_or_else(|| std::string::String::new(), |v| v.to_string()))),
|
||||
Some(
|
||||
quote!(self.#label.map_or_else(|| ::std::string::String::new(), |v| v.to_string())),
|
||||
),
|
||||
quote!({
|
||||
if let Some(ref value) = self.#label {
|
||||
if let ::std::option::Option::Some(ref value) = self.#label {
|
||||
struct_start_event.attr(#label_name, &yaserde_inner)
|
||||
} else {
|
||||
struct_start_event
|
||||
@ -78,7 +81,7 @@ pub fn serialize(
|
||||
field.ser_wrap_default_attribute(
|
||||
None,
|
||||
quote!({
|
||||
if let Some(ref yaserde_list) = self.#label {
|
||||
if let ::std::option::Option::Some(ref yaserde_list) = self.#label {
|
||||
for yaserde_item in yaserde_list.iter() {
|
||||
#inner
|
||||
}
|
||||
@ -87,11 +90,16 @@ pub fn serialize(
|
||||
)
|
||||
}
|
||||
Field::FieldStruct { .. } => field.ser_wrap_default_attribute(
|
||||
Some(quote!(self.#label
|
||||
.as_ref()
|
||||
.map_or_else(|| Ok(std::string::String::new()), |v| yaserde::ser::to_string_content(v))?)),
|
||||
Some(quote! {
|
||||
self.#label
|
||||
.as_ref()
|
||||
.map_or_else(
|
||||
|| ::std::result::Result::Ok(::std::string::String::new()),
|
||||
|v| ::yaserde::ser::to_string_content(v),
|
||||
)?
|
||||
}),
|
||||
quote!({
|
||||
if let Some(ref yaserde_struct) = self.#label {
|
||||
if let ::std::option::Option::Some(ref yaserde_struct) = self.#label {
|
||||
struct_start_event.attr(#label_name, &yaserde_inner)
|
||||
} else {
|
||||
struct_start_event
|
||||
@ -101,7 +109,7 @@ pub fn serialize(
|
||||
Field::FieldOption { .. } => unimplemented!(),
|
||||
},
|
||||
Field::FieldStruct { .. } => field.ser_wrap_default_attribute(
|
||||
Some(quote!(yaserde::ser::to_string_content(&self.#label)?)),
|
||||
Some(quote! { ::yaserde::ser::to_string_content(&self.#label)? }),
|
||||
quote!({
|
||||
struct_start_event.attr(#label_name, &yaserde_inner)
|
||||
}),
|
||||
@ -115,12 +123,15 @@ pub fn serialize(
|
||||
match field.get_type() {
|
||||
Field::FieldStruct { .. } => {
|
||||
quote!(
|
||||
let (attributes, namespace) = self.#label.serialize_attributes(vec![], xml::namespace::Namespace::empty())?;
|
||||
let (attributes, namespace) = self.#label.serialize_attributes(
|
||||
::std::vec![],
|
||||
::xml::namespace::Namespace::empty(),
|
||||
)?;
|
||||
child_attributes_namespace.extend(&namespace);
|
||||
child_attributes.extend(attributes);
|
||||
)
|
||||
}
|
||||
_ => quote!()
|
||||
_ => quote!(),
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -135,7 +146,7 @@ pub fn serialize(
|
||||
let label = field.label();
|
||||
if field.is_text_content() {
|
||||
return Some(quote!(
|
||||
let data_event = XmlEvent::characters(&self.#label);
|
||||
let data_event = ::xml::writer::XmlEvent::characters(&self.#label);
|
||||
writer.write(data_event).map_err(|e| e.to_string())?;
|
||||
));
|
||||
}
|
||||
@ -187,7 +198,7 @@ pub fn serialize(
|
||||
|
||||
Some(quote! {
|
||||
#conditions {
|
||||
if let Some(ref yaserde_items) = &self.#label {
|
||||
if let ::std::option::Option::Some(ref yaserde_items) = &self.#label {
|
||||
for yaserde_item in yaserde_items.iter() {
|
||||
#inner
|
||||
}
|
||||
@ -197,16 +208,16 @@ pub fn serialize(
|
||||
}
|
||||
Field::FieldStruct { .. } => Some(if field.is_flatten() {
|
||||
quote! {
|
||||
if let Some(ref item) = &self.#label {
|
||||
writer.set_start_event_name(None);
|
||||
if let ::std::option::Option::Some(ref item) = &self.#label {
|
||||
writer.set_start_event_name(::std::option::Option::None);
|
||||
writer.set_skip_start_end(true);
|
||||
item.serialize(writer)?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
if let Some(ref item) = &self.#label {
|
||||
writer.set_start_event_name(Some(#label_name.to_string()));
|
||||
if let ::std::option::Option::Some(ref item) = &self.#label {
|
||||
writer.set_start_event_name(::std::option::Option::Some(#label_name.to_string()));
|
||||
writer.set_skip_start_end(false);
|
||||
item.serialize(writer)?;
|
||||
}
|
||||
@ -216,9 +227,12 @@ pub fn serialize(
|
||||
},
|
||||
Field::FieldStruct { .. } => {
|
||||
let (start_event, skip_start) = if field.is_flatten() {
|
||||
(quote!(None), true)
|
||||
(quote!(::std::option::Option::None), true)
|
||||
} else {
|
||||
(quote!(Some(#label_name.to_string())), false)
|
||||
(
|
||||
quote!(::std::option::Option::Some(#label_name.to_string())),
|
||||
false,
|
||||
)
|
||||
};
|
||||
|
||||
Some(quote! {
|
||||
@ -271,7 +285,7 @@ pub fn serialize(
|
||||
if field.is_flatten() {
|
||||
Some(quote! {
|
||||
for item in &self.#label {
|
||||
writer.set_start_event_name(None);
|
||||
writer.set_start_event_name(::std::option::Option::None);
|
||||
writer.set_skip_start_end(true);
|
||||
item.serialize(writer)?;
|
||||
}
|
||||
@ -279,7 +293,7 @@ pub fn serialize(
|
||||
} else {
|
||||
Some(quote! {
|
||||
for item in &self.#label {
|
||||
writer.set_start_event_name(Some(#label_name.to_string()));
|
||||
writer.set_start_event_name(::std::option::Option::Some(#label_name.to_string()));
|
||||
writer.set_skip_start_end(false);
|
||||
item.serialize(writer)?;
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ use crate::common::YaSerdeAttribute;
|
||||
use crate::ser::namespace::generate_namespaces_definition;
|
||||
use proc_macro2::Ident;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
pub fn implement_serializer(
|
||||
name: &Ident,
|
||||
@ -14,26 +15,32 @@ pub fn implement_serializer(
|
||||
let flatten = attributes.flatten;
|
||||
|
||||
quote! {
|
||||
use xml::writer::XmlEvent;
|
||||
|
||||
impl YaSerialize for #name {
|
||||
impl ::yaserde::YaSerialize for #name {
|
||||
#[allow(unused_variables)]
|
||||
fn serialize<W: Write>(&self, writer: &mut yaserde::ser::Serializer<W>)
|
||||
-> Result<(), std::string::String> {
|
||||
fn serialize<W: ::std::io::Write>(
|
||||
&self,
|
||||
writer: &mut ::yaserde::ser::Serializer<W>,
|
||||
) -> ::std::result::Result<(), ::std::string::String> {
|
||||
let skip = writer.skip_start_end();
|
||||
|
||||
if !#flatten && !skip {
|
||||
let mut child_attributes = vec![];
|
||||
let mut child_attributes_namespace = xml::namespace::Namespace::empty();
|
||||
let mut child_attributes = ::std::vec![];
|
||||
let mut child_attributes_namespace = ::xml::namespace::Namespace::empty();
|
||||
|
||||
let yaserde_label = writer.get_start_event_name().unwrap_or_else(|| #root.to_string());
|
||||
let struct_start_event = XmlEvent::start_element(yaserde_label.as_ref())#namespaces_definition;
|
||||
let struct_start_event =
|
||||
::xml::writer::XmlEvent::start_element(yaserde_label.as_ref()) #namespaces_definition;
|
||||
#append_attributes
|
||||
|
||||
let event : xml::writer::events::XmlEvent = struct_start_event.into();
|
||||
let event: ::xml::writer::events::XmlEvent = struct_start_event.into();
|
||||
|
||||
if let xml::writer::events::XmlEvent::StartElement{name, attributes, namespace} = event {
|
||||
let mut attributes: Vec<xml::attribute::OwnedAttribute> = attributes.into_owned().to_vec().iter().map(|k| k.to_owned()).collect();
|
||||
if let ::xml::writer::events::XmlEvent::StartElement {
|
||||
name,
|
||||
attributes,
|
||||
namespace,
|
||||
} = event {
|
||||
let mut attributes: ::std::vec::Vec<::xml::attribute::OwnedAttribute> =
|
||||
attributes.into_owned().to_vec().iter().map(|k| k.to_owned()).collect();
|
||||
attributes.extend(child_attributes);
|
||||
|
||||
let all_attributes = attributes.iter().map(|ca| ca.borrow()).collect();
|
||||
@ -41,10 +48,10 @@ pub fn implement_serializer(
|
||||
let mut all_namespaces = namespace.into_owned();
|
||||
all_namespaces.extend(&child_attributes_namespace);
|
||||
|
||||
writer.write(xml::writer::events::XmlEvent::StartElement{
|
||||
writer.write(::xml::writer::events::XmlEvent::StartElement{
|
||||
name,
|
||||
attributes: std::borrow::Cow::Owned(all_attributes),
|
||||
namespace: std::borrow::Cow::Owned(all_namespaces)
|
||||
attributes: ::std::borrow::Cow::Owned(all_attributes),
|
||||
namespace: ::std::borrow::Cow::Owned(all_namespaces)
|
||||
}).map_err(|e| e.to_string())?;
|
||||
} else {
|
||||
unreachable!()
|
||||
@ -54,30 +61,41 @@ pub fn implement_serializer(
|
||||
#inner_inspector
|
||||
|
||||
if !#flatten && !skip {
|
||||
let struct_end_event = XmlEvent::end_element();
|
||||
let struct_end_event = ::xml::writer::XmlEvent::end_element();
|
||||
writer.write(struct_end_event).map_err(|e| e.to_string())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
|
||||
fn serialize_attributes(&self, mut source_attributes: Vec<xml::attribute::OwnedAttribute>, mut source_namespace: xml::namespace::Namespace) -> Result<(Vec<xml::attribute::OwnedAttribute>, xml::namespace::Namespace), std::string::String> {
|
||||
let mut child_attributes : Vec<xml::attribute::OwnedAttribute> = vec![];
|
||||
let mut child_attributes_namespace = xml::namespace::Namespace::empty();
|
||||
fn serialize_attributes(
|
||||
&self,
|
||||
mut source_attributes: ::std::vec::Vec<::xml::attribute::OwnedAttribute>,
|
||||
mut source_namespace: ::xml::namespace::Namespace,
|
||||
) -> ::std::result::Result<
|
||||
(::std::vec::Vec<::xml::attribute::OwnedAttribute>, ::xml::namespace::Namespace),
|
||||
::std::string::String
|
||||
> {
|
||||
let mut child_attributes = ::std::vec::Vec::<::xml::attribute::OwnedAttribute>::new();
|
||||
let mut child_attributes_namespace = ::xml::namespace::Namespace::empty();
|
||||
|
||||
let struct_start_event =
|
||||
::xml::writer::XmlEvent::start_element("temporary_element_to_generate_attributes")
|
||||
#namespaces_definition;
|
||||
|
||||
let struct_start_event = XmlEvent::start_element("temporary_element_to_generate_attributes")#namespaces_definition;
|
||||
#append_attributes
|
||||
let event : xml::writer::events::XmlEvent = struct_start_event.into();
|
||||
let event: ::xml::writer::events::XmlEvent = struct_start_event.into();
|
||||
|
||||
if let xml::writer::events::XmlEvent::StartElement{attributes, namespace, ..} = event {
|
||||
if let ::xml::writer::events::XmlEvent::StartElement { attributes, namespace, .. } = event {
|
||||
source_namespace.extend(&namespace.into_owned());
|
||||
source_namespace.extend(&child_attributes_namespace);
|
||||
|
||||
let a: Vec<xml::attribute::OwnedAttribute> = attributes.into_owned().to_vec().iter().map(|k| k.to_owned()).collect();
|
||||
let a: ::std::vec::Vec<::xml::attribute::OwnedAttribute> =
|
||||
attributes.into_owned().to_vec().iter().map(|k| k.to_owned()).collect();
|
||||
source_attributes.extend(a);
|
||||
source_attributes.extend(child_attributes);
|
||||
|
||||
Ok((source_attributes, source_namespace))
|
||||
::std::result::Result::Ok((source_attributes, source_namespace))
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
@ -6,8 +6,8 @@ pub mod label;
|
||||
pub mod namespace;
|
||||
|
||||
use crate::common::YaSerdeAttribute;
|
||||
use proc_macro2::TokenStream;
|
||||
use syn::Ident;
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::quote;
|
||||
|
||||
pub fn expand_derive_serialize(ast: &syn::DeriveInput) -> Result<TokenStream, String> {
|
||||
let name = &ast.ident;
|
||||
@ -34,13 +34,12 @@ pub fn expand_derive_serialize(ast: &syn::DeriveInput) -> Result<TokenStream, St
|
||||
|
||||
let dummy_const = Ident::new(&format!("_IMPL_YA_SERIALIZE_FOR_{}", name), name.span());
|
||||
|
||||
let generated = quote! {
|
||||
Ok(quote! {
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const #dummy_const: () = {
|
||||
extern crate yaserde as _yaserde;
|
||||
use ::std::str::FromStr as _;
|
||||
|
||||
#impl_block
|
||||
};
|
||||
};
|
||||
|
||||
Ok(generated)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use crate::common::YaSerdeAttribute;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
pub fn generate_namespaces_definition(attributes: &YaSerdeAttribute) -> TokenStream {
|
||||
attributes
|
||||
|
||||
Loading…
Reference in New Issue
Block a user