Compare commits
No commits in common. "353558737f3ef73e93164c596ff920d4344f30a3" and "177fa8e5a73055294adf3719445e433526e16ee0" have entirely different histories.
353558737f
...
177fa8e5a7
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "yaserde-examples"
|
name = "yaserde-examples"
|
||||||
version = "0.11.1"
|
version = "0.10.0"
|
||||||
authors = ["Marc-Antoine Arnaud <maarnaud@media-io.com>"]
|
authors = ["Marc-Antoine Arnaud <maarnaud@media-io.com>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
@ -8,4 +8,4 @@ description = "Examples for YaSerDe project"
|
|||||||
documentation = "https://docs.rs/yaserde"
|
documentation = "https://docs.rs/yaserde"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
yaserde = {version = "0.11.1", path = "../yaserde", features = ["yaserde_derive"] }
|
yaserde = {version = "0.10.0", path = "../yaserde", features = ["yaserde_derive"] }
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use yaserde::*;
|
|||||||
namespace = "html: http://www.w3.org/TR/REC-html40"
|
namespace = "html: http://www.w3.org/TR/REC-html40"
|
||||||
)]
|
)]
|
||||||
struct Workbook {
|
struct Workbook {
|
||||||
#[yaserde(rename = "Worksheet", prefix = "ss")]
|
#[yaserde(rename = "Worksheet")]
|
||||||
worksheet: Worksheet,
|
worksheet: Worksheet,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ struct Workbook {
|
|||||||
namespace = "html: http://www.w3.org/TR/REC-html40"
|
namespace = "html: http://www.w3.org/TR/REC-html40"
|
||||||
)]
|
)]
|
||||||
struct Worksheet {
|
struct Worksheet {
|
||||||
#[yaserde(rename = "Table", prefix = "ss")]
|
#[yaserde(rename = "Table")]
|
||||||
table: Table,
|
table: Table,
|
||||||
#[yaserde(attribute, rename = "Name", prefix = "ss")]
|
#[yaserde(attribute, rename = "Name", prefix = "ss")]
|
||||||
ws_name: String,
|
ws_name: String,
|
||||||
@ -53,7 +53,7 @@ struct Table {
|
|||||||
#[yaserde(attribute, rename = "DefaultRowHeight", prefix = "ss")]
|
#[yaserde(attribute, rename = "DefaultRowHeight", prefix = "ss")]
|
||||||
default_column_height: f32,
|
default_column_height: f32,
|
||||||
|
|
||||||
#[yaserde(rename = "Row", prefix = "ss")]
|
#[yaserde(rename = "Row")]
|
||||||
rows: Vec<Row>,
|
rows: Vec<Row>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,102 +0,0 @@
|
|||||||
use yaserde::*;
|
|
||||||
|
|
||||||
#[derive(YaSerialize, YaDeserialize, Debug, Default, Clone, Eq, PartialEq)]
|
|
||||||
pub struct Header {}
|
|
||||||
|
|
||||||
#[derive(YaSerialize, YaDeserialize, Debug, Default, Clone, Eq, PartialEq)]
|
|
||||||
#[yaserde(
|
|
||||||
rename = "Envelope",
|
|
||||||
namespace = "s: http://schemas.xmlsoap.org/soap/envelope/",
|
|
||||||
prefix = "s"
|
|
||||||
)]
|
|
||||||
pub struct SoapEnvelope<BODY>
|
|
||||||
where
|
|
||||||
BODY: YaSerialize + YaDeserialize + Default,
|
|
||||||
{
|
|
||||||
#[yaserde(rename = "encodingStyle", prefix = "s", attribute)]
|
|
||||||
pub encoding_style: String,
|
|
||||||
#[yaserde(rename = "u", prefix = "xmlns", attribute)]
|
|
||||||
pub tnsattr: Option<String>,
|
|
||||||
#[yaserde(rename = "urn", prefix = "xmlns", attribute)]
|
|
||||||
pub urnattr: Option<String>,
|
|
||||||
#[yaserde(rename = "xsi", prefix = "xmlns", attribute)]
|
|
||||||
pub xsiattr: Option<String>,
|
|
||||||
#[yaserde(rename = "Header", prefix = "s")]
|
|
||||||
pub header: Option<Header>,
|
|
||||||
#[yaserde(rename = "Body", prefix = "s")]
|
|
||||||
pub body: BODY,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(YaSerialize, YaDeserialize, Debug, Default, Clone, Eq, PartialEq)]
|
|
||||||
#[yaserde(namespace = "u: urn:schemas-upnp-org:service:AVTransport:1")]
|
|
||||||
pub struct SoapPlay {
|
|
||||||
#[yaserde(rename = "Play", prefix = "u", default)]
|
|
||||||
pub body: Play,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(YaSerialize, YaDeserialize, Debug, Default, Clone, Eq, PartialEq)]
|
|
||||||
#[yaserde(rename = "Play", prefix = "u")]
|
|
||||||
pub struct Play {
|
|
||||||
#[yaserde(flatten, default)]
|
|
||||||
pub parameters: Play2,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(YaSerialize, YaDeserialize, Debug, Default, Clone, Eq, PartialEq)]
|
|
||||||
#[yaserde(
|
|
||||||
rename = "Play",
|
|
||||||
namespace = "u: urn:schemas-upnp-org:service:AVTransport:1",
|
|
||||||
prefix = "u"
|
|
||||||
)]
|
|
||||||
pub struct Play2 {
|
|
||||||
#[yaserde(rename = "InstanceID", default)]
|
|
||||||
pub instance_id: i32,
|
|
||||||
#[yaserde(rename = "Speed", default)]
|
|
||||||
pub speed: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PrimitiveYaSerde, Debug, Default, Eq, PartialEq)]
|
|
||||||
struct Meters(i32);
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_for_generic_newtype() {
|
|
||||||
let a = SoapEnvelope {
|
|
||||||
encoding_style: "".to_string(),
|
|
||||||
tnsattr: None,
|
|
||||||
urnattr: None,
|
|
||||||
xsiattr: None,
|
|
||||||
header: None,
|
|
||||||
body: Meters(10),
|
|
||||||
};
|
|
||||||
|
|
||||||
let s = ser::to_string(&a).unwrap();
|
|
||||||
let b: SoapEnvelope<Meters> = de::from_str(&s).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(a, b);
|
|
||||||
println!("{:#?}", b);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_for_generic_nested_struct() {
|
|
||||||
let a = SoapEnvelope {
|
|
||||||
encoding_style: "".to_string(),
|
|
||||||
tnsattr: None,
|
|
||||||
urnattr: None,
|
|
||||||
xsiattr: None,
|
|
||||||
header: None,
|
|
||||||
body: SoapPlay {
|
|
||||||
body: Play {
|
|
||||||
parameters: Play2 {
|
|
||||||
instance_id: 20,
|
|
||||||
speed: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let s = ser::to_string(&a).unwrap();
|
|
||||||
println!("{s}");
|
|
||||||
let b: SoapEnvelope<SoapPlay> = de::from_str(&s).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(a, b);
|
|
||||||
println!("{:#?}", b);
|
|
||||||
}
|
|
||||||
@ -1,6 +1,4 @@
|
|||||||
mod bbigras_namespace;
|
mod bbigras_namespace;
|
||||||
mod boscop;
|
mod boscop;
|
||||||
mod generic;
|
|
||||||
mod ln_dom;
|
mod ln_dom;
|
||||||
mod same_element_different_namespaces;
|
|
||||||
mod svd;
|
mod svd;
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
// related to issue https://github.com/media-io/yaserde/issues/186
|
|
||||||
use yaserde::*;
|
|
||||||
|
|
||||||
#[derive(YaDeserialize, Debug, PartialEq)]
|
|
||||||
#[yaserde(
|
|
||||||
namespace = "myns: http://my_namespace_1/",
|
|
||||||
namespace = "ext: http://my_namespace_2/",
|
|
||||||
prefix = "myns"
|
|
||||||
)]
|
|
||||||
pub struct ErrorType {
|
|
||||||
#[yaserde(rename = "reasonCode", prefix = "myns")]
|
|
||||||
pub reason_code: Option<u16>,
|
|
||||||
#[yaserde(rename = "reasonCode", prefix = "ext")]
|
|
||||||
pub ext_reason_code: Option<u16>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn same_element_different_namespaces() {
|
|
||||||
use yaserde::de::from_str;
|
|
||||||
|
|
||||||
let content = r#"
|
|
||||||
<error_type xmlns="http://my_namespace_1/" xmlns:ext="http://my_namespace_2/">
|
|
||||||
<reasonCode>12</reasonCode>
|
|
||||||
<ext:reasonCode>32</ext:reasonCode>
|
|
||||||
</error_type>
|
|
||||||
"#;
|
|
||||||
|
|
||||||
let loaded: ErrorType = from_str(content).unwrap();
|
|
||||||
println!("{:?}", loaded);
|
|
||||||
|
|
||||||
let reference = ErrorType {
|
|
||||||
reason_code: Some(12),
|
|
||||||
ext_reason_code: Some(32),
|
|
||||||
};
|
|
||||||
|
|
||||||
assert_eq!(loaded, reference);
|
|
||||||
}
|
|
||||||
@ -1,123 +1,124 @@
|
|||||||
|
use yaserde::YaSerialize;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, YaSerialize)]
|
||||||
|
struct CpuDef {
|
||||||
|
#[yaserde(child)]
|
||||||
|
name: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
revision: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
endian: String, // enum {LE, BE, ME}
|
||||||
|
#[yaserde(child)]
|
||||||
|
mpupresent: bool,
|
||||||
|
#[yaserde(child)]
|
||||||
|
fpupresent: bool,
|
||||||
|
//#[yaserde(child)]
|
||||||
|
//nvicpriobits: enum {8, 16, 32, 64, 128},
|
||||||
|
#[yaserde(child)]
|
||||||
|
vendorsystickconfig: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, YaSerialize)]
|
||||||
|
struct Field {
|
||||||
|
name: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
description: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
bitrange: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
access: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, YaSerialize)]
|
||||||
|
struct Register {
|
||||||
|
#[yaserde(child)]
|
||||||
|
name: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
description: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
addressoffset: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
size: u8,
|
||||||
|
#[yaserde(child)]
|
||||||
|
access: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
resetvalue: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
resetmask: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
fields: Vec<Field>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, YaSerialize)]
|
||||||
|
struct Peripheral {
|
||||||
|
#[yaserde(child)]
|
||||||
|
name: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
version: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
description: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
groupname: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
baseaddress: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
size: u8,
|
||||||
|
#[yaserde(child)]
|
||||||
|
access: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
registers: Vec<Register>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, YaSerialize)]
|
||||||
|
struct DevAttrs {
|
||||||
|
#[yaserde(child)]
|
||||||
|
vendor: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
vendorid: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
name: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
series: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
version: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
description: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
licensetext: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
cpu: CpuDef,
|
||||||
|
#[yaserde(child)]
|
||||||
|
addressunitbits: u8,
|
||||||
|
#[yaserde(child)]
|
||||||
|
width: u8,
|
||||||
|
#[yaserde(child)]
|
||||||
|
size: u8,
|
||||||
|
#[yaserde(child)]
|
||||||
|
access: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
resetvalue: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
resetmask: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
peripherals: Vec<Peripheral>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, YaSerialize)]
|
||||||
|
#[yaserde(rename = "device")]
|
||||||
|
struct Device {
|
||||||
|
#[yaserde(attribute)]
|
||||||
|
schemaversion: String,
|
||||||
|
#[yaserde(attribute)]
|
||||||
|
xmlns: String,
|
||||||
|
#[yaserde(attribute)]
|
||||||
|
xsnonamespaceschemalocation: String,
|
||||||
|
#[yaserde(child)]
|
||||||
|
devattributes: DevAttrs,
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parsing_svd() {
|
fn parsing_svd() {
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use yaserde::YaSerialize;
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, YaSerialize)]
|
|
||||||
struct CpuDef {
|
|
||||||
#[yaserde(child)]
|
|
||||||
name: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
revision: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
endian: String, // enum {LE, BE, ME}
|
|
||||||
#[yaserde(child)]
|
|
||||||
mpupresent: bool,
|
|
||||||
#[yaserde(child)]
|
|
||||||
fpupresent: bool,
|
|
||||||
//#[yaserde(child)]
|
|
||||||
//nvicpriobits: enum {8, 16, 32, 64, 128},
|
|
||||||
#[yaserde(child)]
|
|
||||||
vendorsystickconfig: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, YaSerialize)]
|
|
||||||
struct Field {
|
|
||||||
name: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
description: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
bitrange: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
access: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, YaSerialize)]
|
|
||||||
struct Register {
|
|
||||||
#[yaserde(child)]
|
|
||||||
name: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
description: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
addressoffset: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
size: u8,
|
|
||||||
#[yaserde(child)]
|
|
||||||
access: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
resetvalue: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
resetmask: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
fields: Vec<Field>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, YaSerialize)]
|
|
||||||
struct Peripheral {
|
|
||||||
#[yaserde(child)]
|
|
||||||
name: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
version: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
description: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
groupname: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
baseaddress: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
size: u8,
|
|
||||||
#[yaserde(child)]
|
|
||||||
access: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
registers: Vec<Register>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, YaSerialize)]
|
|
||||||
struct DevAttrs {
|
|
||||||
#[yaserde(child)]
|
|
||||||
vendor: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
vendorid: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
name: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
series: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
version: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
description: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
licensetext: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
cpu: CpuDef,
|
|
||||||
#[yaserde(child)]
|
|
||||||
addressunitbits: u8,
|
|
||||||
#[yaserde(child)]
|
|
||||||
width: u8,
|
|
||||||
#[yaserde(child)]
|
|
||||||
size: u8,
|
|
||||||
#[yaserde(child)]
|
|
||||||
access: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
resetvalue: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
resetmask: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
peripherals: Vec<Peripheral>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, YaSerialize)]
|
|
||||||
#[yaserde(rename = "device")]
|
|
||||||
struct Device {
|
|
||||||
#[yaserde(attribute)]
|
|
||||||
schemaversion: String,
|
|
||||||
#[yaserde(attribute)]
|
|
||||||
xmlns: String,
|
|
||||||
#[yaserde(attribute)]
|
|
||||||
xsnonamespaceschemalocation: String,
|
|
||||||
#[yaserde(child)]
|
|
||||||
devattributes: DevAttrs,
|
|
||||||
}
|
|
||||||
|
|
||||||
let register = Register {
|
let register = Register {
|
||||||
name: "PRCMD".to_string(),
|
name: "PRCMD".to_string(),
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "yaserde"
|
name = "yaserde"
|
||||||
version = "0.11.1"
|
version = "0.10.0"
|
||||||
authors = ["Marc-Antoine Arnaud <arnaud.marcantoine@gmail.com>"]
|
authors = ["Marc-Antoine Arnaud <arnaud.marcantoine@gmail.com>"]
|
||||||
description = "Serialization and deserialization library"
|
description = "Serialization and deserialization library"
|
||||||
keywords = ["Serialization", "Deserialization", "XML"]
|
keywords = ["Serialization", "Deserialization", "XML"]
|
||||||
@ -12,13 +12,13 @@ readme = "../README.md"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
yaserde_derive = { version = "0.11.1", path = "../yaserde_derive", optional = true }
|
yaserde_derive = { version = "0.10.0", path = "../yaserde_derive", optional = true }
|
||||||
xml-rs = "0.8.3"
|
xml-rs = "0.8.3"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
env_logger = "0.11.0"
|
env_logger = "0.11.0"
|
||||||
yaserde_derive = { version = "0.11.1", path = "../yaserde_derive" }
|
yaserde_derive = { version = "0.10.0", path = "../yaserde_derive" }
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
travis-ci = { repository = "media-io/yaserde" }
|
travis-ci = { repository = "media-io/yaserde" }
|
||||||
|
|||||||
@ -94,7 +94,6 @@ use std::io::{Read, Write};
|
|||||||
use xml::writer::XmlEvent;
|
use xml::writer::XmlEvent;
|
||||||
|
|
||||||
pub mod de;
|
pub mod de;
|
||||||
pub mod primitives;
|
|
||||||
pub mod ser;
|
pub mod ser;
|
||||||
|
|
||||||
/// A **data structure** that can be deserialized from any data format supported by YaSerDe.
|
/// A **data structure** that can be deserialized from any data format supported by YaSerDe.
|
||||||
|
|||||||
@ -1,51 +0,0 @@
|
|||||||
use std::{io::Read, io::Write};
|
|
||||||
|
|
||||||
use crate::{de, ser};
|
|
||||||
|
|
||||||
pub fn serialize_primitives<S, W: Write>(
|
|
||||||
self_bypass: &S,
|
|
||||||
default_name: &str,
|
|
||||||
writer: &mut ser::Serializer<W>,
|
|
||||||
serialize_function: impl FnOnce(&S) -> String,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
let name = writer
|
|
||||||
.get_start_event_name()
|
|
||||||
.unwrap_or_else(|| default_name.to_string());
|
|
||||||
|
|
||||||
if !writer.skip_start_end() {
|
|
||||||
writer
|
|
||||||
.write(xml::writer::XmlEvent::start_element(name.as_str()))
|
|
||||||
.map_err(|_e| format!("Start element {name:?} write failed"))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
writer
|
|
||||||
.write(xml::writer::XmlEvent::characters(
|
|
||||||
serialize_function(self_bypass).as_str(),
|
|
||||||
))
|
|
||||||
.map_err(|_e| format!("Element value {name:?} write failed"))?;
|
|
||||||
|
|
||||||
if !writer.skip_start_end() {
|
|
||||||
writer
|
|
||||||
.write(xml::writer::XmlEvent::end_element())
|
|
||||||
.map_err(|_e| format!("End element {name:?} write failed"))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deserialize_primitives<S, R: Read>(
|
|
||||||
reader: &mut de::Deserializer<R>,
|
|
||||||
deserialize_function: impl FnOnce(&str) -> Result<S, String>,
|
|
||||||
) -> Result<S, String> {
|
|
||||||
if let Ok(xml::reader::XmlEvent::StartElement { .. }) = reader.peek() {
|
|
||||||
reader.next_event()?;
|
|
||||||
} else {
|
|
||||||
return Err("Start element not found".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(xml::reader::XmlEvent::Characters(ref text)) = reader.peek() {
|
|
||||||
deserialize_function(text)
|
|
||||||
} else {
|
|
||||||
deserialize_function("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1117,20 +1117,3 @@ fn de_nested_macro_rules() {
|
|||||||
|
|
||||||
float_attrs!(f32);
|
float_attrs!(f32);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn de_strict() {
|
|
||||||
init();
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, YaDeserialize)]
|
|
||||||
pub struct Struct {
|
|
||||||
id: i32,
|
|
||||||
}
|
|
||||||
let xml_content = r#"<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Struct>
|
|
||||||
<id>123</id>
|
|
||||||
<NonExistentAttrShouldCrash></NonExistentAttrShouldCrash>
|
|
||||||
</Struct>"#;
|
|
||||||
let load: Result<Struct, String> = from_str(xml_content);
|
|
||||||
assert!(load.is_err());
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,41 +0,0 @@
|
|||||||
#[macro_use]
|
|
||||||
extern crate yaserde;
|
|
||||||
|
|
||||||
use yaserde::{YaDeserialize, YaSerialize};
|
|
||||||
|
|
||||||
fn init() {
|
|
||||||
let _ = env_logger::builder().is_test(true).try_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn generic() {
|
|
||||||
init();
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, YaDeserialize, YaSerialize)]
|
|
||||||
#[yaserde(rename = "base")]
|
|
||||||
pub struct Base<G>
|
|
||||||
where
|
|
||||||
G: YaSerialize + YaDeserialize + Default,
|
|
||||||
{
|
|
||||||
background: G,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq, YaDeserialize, YaSerialize)]
|
|
||||||
pub struct Generic {
|
|
||||||
#[yaserde(attribute)]
|
|
||||||
color: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
let content = r#"<base><background color="blue" /></base>"#;
|
|
||||||
let model = Base {
|
|
||||||
background: Generic {
|
|
||||||
color: "blue".to_string(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
serialize_and_validate!(model, content);
|
|
||||||
|
|
||||||
log::debug!("deserialize_and_validate @ {}:{}", file!(), line!());
|
|
||||||
let loaded: Result<Base<Generic>, String> = yaserde::de::from_str(content);
|
|
||||||
assert_eq!(loaded, Ok(model));
|
|
||||||
}
|
|
||||||
@ -47,7 +47,7 @@ fn skip_serializing_if_for_struct() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn check_f32_function(&self, value: &f32) -> bool {
|
fn check_f32_function(&self, value: &f32) -> bool {
|
||||||
(value - 0.0).abs() < f32::EPSILON
|
(value - 0.0).abs() < std::f32::EPSILON
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ fn skip_serializing_if_for_struct_attributes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn check_f32_function(&self, value: &f32) -> bool {
|
fn check_f32_function(&self, value: &f32) -> bool {
|
||||||
(value - 0.0).abs() < f32::EPSILON
|
(value - 0.0).abs() < std::f32::EPSILON
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "yaserde_derive"
|
name = "yaserde_derive"
|
||||||
version = "0.11.1"
|
version = "0.10.0"
|
||||||
authors = ["Marc-Antoine Arnaud <arnaud.marcantoine@gmail.com>"]
|
authors = ["Marc-Antoine Arnaud <arnaud.marcantoine@gmail.com>"]
|
||||||
description = "Serialization and deserialization macros"
|
description = "Serialization and deserialization macros"
|
||||||
keywords = ["Serialization", "Deserialization"]
|
keywords = ["Serialization", "Deserialization"]
|
||||||
@ -12,7 +12,7 @@ readme = "../README.md"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
heck = "0.5"
|
heck = "0.4.0"
|
||||||
syn = { version = "~1.0", features = ["visit", "extra-traits"] }
|
syn = { version = "~1.0", features = ["visit", "extra-traits"] }
|
||||||
proc-macro2 = "~1.0"
|
proc-macro2 = "~1.0"
|
||||||
quote = "~1.0"
|
quote = "~1.0"
|
||||||
|
|||||||
@ -90,13 +90,6 @@ impl YaSerdeField {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let prefix = self
|
|
||||||
.attributes
|
|
||||||
.prefix
|
|
||||||
.clone()
|
|
||||||
.map(|p| format!("{}_", p.to_upper_camel_case()))
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let attribute = self
|
let attribute = self
|
||||||
.attributes
|
.attributes
|
||||||
.attribute
|
.attribute
|
||||||
@ -105,8 +98,7 @@ impl YaSerdeField {
|
|||||||
|
|
||||||
Ident::new(
|
Ident::new(
|
||||||
&format!(
|
&format!(
|
||||||
"__Visitor_{attribute}{}{}_{}",
|
"__Visitor_{attribute}{}_{}",
|
||||||
prefix,
|
|
||||||
label.replace('.', "_").to_upper_camel_case(),
|
label.replace('.', "_").to_upper_camel_case(),
|
||||||
struct_id
|
struct_id
|
||||||
),
|
),
|
||||||
@ -138,20 +130,6 @@ impl YaSerdeField {
|
|||||||
.map(|skip_serializing_if| Ident::new(skip_serializing_if, self.get_span()))
|
.map(|skip_serializing_if| Ident::new(skip_serializing_if, self.get_span()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prefix_namespace(&self, root_attributes: &YaSerdeAttribute) -> String {
|
|
||||||
root_attributes
|
|
||||||
.namespaces
|
|
||||||
.iter()
|
|
||||||
.find_map(|(prefix, namespace)| {
|
|
||||||
if self.attributes.prefix.eq(prefix) {
|
|
||||||
Some(namespace.clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_namespace_matching(
|
pub fn get_namespace_matching(
|
||||||
&self,
|
&self,
|
||||||
root_attributes: &YaSerdeAttribute,
|
root_attributes: &YaSerdeAttribute,
|
||||||
@ -283,7 +261,7 @@ impl From<&syn::PathSegment> for Field {
|
|||||||
return Field::from(&path.path);
|
return Field::from(&path.path);
|
||||||
}
|
}
|
||||||
Some(syn::GenericArgument::Type(syn::Type::Group(syn::TypeGroup { elem, .. }))) => {
|
Some(syn::GenericArgument::Type(syn::Type::Group(syn::TypeGroup { elem, .. }))) => {
|
||||||
if let Path(ref group) = elem.as_ref() {
|
if let syn::Type::Path(ref group) = elem.as_ref() {
|
||||||
return Field::from(&group.path);
|
return Field::from(&group.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
use crate::common::{Field, YaSerdeAttribute, YaSerdeField};
|
use crate::common::{Field, YaSerdeAttribute, YaSerdeField};
|
||||||
use proc_macro2::{Span, TokenStream};
|
use proc_macro2::{Span, TokenStream};
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::{DataEnum, Fields, Generics, Ident};
|
use syn::{DataEnum, Fields, Ident};
|
||||||
|
|
||||||
pub fn parse(
|
pub fn parse(
|
||||||
data_enum: &DataEnum,
|
data_enum: &DataEnum,
|
||||||
name: &Ident,
|
name: &Ident,
|
||||||
root: &str,
|
root: &str,
|
||||||
root_attributes: &YaSerdeAttribute,
|
root_attributes: &YaSerdeAttribute,
|
||||||
generics: &Generics,
|
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let namespaces_matching = root_attributes.get_namespace_matching(
|
let namespaces_matching = root_attributes.get_namespace_matching(
|
||||||
&None,
|
&None,
|
||||||
@ -24,7 +23,6 @@ pub fn parse(
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let flatten = root_attributes.flatten;
|
let flatten = root_attributes.flatten;
|
||||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
|
||||||
|
|
||||||
let element_name = if let Some(tag) = &root_attributes.tag {
|
let element_name = if let Some(tag) = &root_attributes.tag {
|
||||||
quote! {
|
quote! {
|
||||||
@ -41,7 +39,7 @@ pub fn parse(
|
|||||||
};
|
};
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
impl #impl_generics ::yaserde::YaDeserialize for #name #ty_generics #where_clause {
|
impl ::yaserde::YaDeserialize for #name {
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn deserialize<R: ::std::io::Read>(
|
fn deserialize<R: ::std::io::Read>(
|
||||||
reader: &mut ::yaserde::de::Deserializer<R>,
|
reader: &mut ::yaserde::de::Deserializer<R>,
|
||||||
|
|||||||
@ -2,15 +2,13 @@ use super::build_default_value::{build_default_value, build_default_vec_value};
|
|||||||
use crate::common::{Field, YaSerdeAttribute, YaSerdeField};
|
use crate::common::{Field, YaSerdeAttribute, YaSerdeField};
|
||||||
use proc_macro2::{Span, TokenStream};
|
use proc_macro2::{Span, TokenStream};
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::{DataStruct, Generics, Ident};
|
use syn::{DataStruct, Ident};
|
||||||
|
|
||||||
pub fn parse(
|
pub fn parse(
|
||||||
data_struct: &DataStruct,
|
data_struct: &DataStruct,
|
||||||
name: &Ident,
|
name: &Ident,
|
||||||
root_namespace: &str,
|
|
||||||
root: &str,
|
root: &str,
|
||||||
root_attributes: &YaSerdeAttribute,
|
root_attributes: &YaSerdeAttribute,
|
||||||
generics: &Generics,
|
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let namespaces_matching = root_attributes.get_namespace_matching(
|
let namespaces_matching = root_attributes.get_namespace_matching(
|
||||||
&None,
|
&None,
|
||||||
@ -51,17 +49,6 @@ pub fn parse(
|
|||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|field| YaSerdeField::new(field.clone()))
|
.map(|field| YaSerdeField::new(field.clone()))
|
||||||
.filter(|field| {
|
|
||||||
if field.is_attribute() {
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
match field.get_type() {
|
|
||||||
Field::FieldVec { data_type } => !matches!(*data_type, Field::FieldStruct { .. }),
|
|
||||||
Field::FieldOption { data_type } => !matches!(*data_type, Field::FieldStruct { .. }),
|
|
||||||
Field::FieldStruct { .. } => false,
|
|
||||||
_ => true,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter_map(|field| {
|
.filter_map(|field| {
|
||||||
let struct_visitor = |struct_name: syn::Path| {
|
let struct_visitor = |struct_name: syn::Path| {
|
||||||
let struct_id: String = struct_name
|
let struct_id: String = struct_name
|
||||||
@ -149,11 +136,9 @@ pub fn parse(
|
|||||||
let value_label = field.get_value_label();
|
let value_label = field.get_value_label();
|
||||||
let label_name = field.renamed_label_without_namespace();
|
let label_name = field.renamed_label_without_namespace();
|
||||||
|
|
||||||
let namespace = field.prefix_namespace(root_attributes);
|
|
||||||
|
|
||||||
let visit_struct = |struct_name: syn::Path, action: TokenStream| {
|
let visit_struct = |struct_name: syn::Path, action: TokenStream| {
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
(#namespace, #label_name) => {
|
#label_name => {
|
||||||
if depth == 0 {
|
if depth == 0 {
|
||||||
// Don't count current struct's StartElement as substruct's StartElement
|
// Don't count current struct's StartElement as substruct's StartElement
|
||||||
let _root = reader.next_event();
|
let _root = reader.next_event();
|
||||||
@ -384,10 +369,9 @@ pub fn parse(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let flatten = root_attributes.flatten;
|
let flatten = root_attributes.flatten;
|
||||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
impl #impl_generics ::yaserde::YaDeserialize for #name #ty_generics #where_clause {
|
impl ::yaserde::YaDeserialize for #name {
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn deserialize<R: ::std::io::Read>(
|
fn deserialize<R: ::std::io::Read>(
|
||||||
reader: &mut ::yaserde::de::Deserializer<R>,
|
reader: &mut ::yaserde::de::Deserializer<R>,
|
||||||
@ -420,20 +404,15 @@ pub fn parse(
|
|||||||
);
|
);
|
||||||
match event {
|
match event {
|
||||||
::yaserde::__xml::reader::XmlEvent::StartElement{ref name, ref attributes, ..} => {
|
::yaserde::__xml::reader::XmlEvent::StartElement{ref name, ref attributes, ..} => {
|
||||||
let namespace = name.namespace.clone().unwrap_or_default();
|
if depth == 0 && name.local_name == #root {
|
||||||
if depth == 0 && name.local_name == #root && namespace.as_str() == #root_namespace {
|
|
||||||
// Consume root element. We must do this first. In the case it shares a name with a child element, we don't
|
// Consume root element. We must do this first. In the case it shares a name with a child element, we don't
|
||||||
// want to prematurely match the child element below.
|
// want to prematurely match the child element below.
|
||||||
let event = reader.next_event()?;
|
let event = reader.next_event()?;
|
||||||
#write_unused
|
#write_unused
|
||||||
} else {
|
} else {
|
||||||
|
match name.local_name.as_str() {
|
||||||
match (namespace.as_str(), name.local_name.as_str()) {
|
|
||||||
#call_visitors
|
#call_visitors
|
||||||
_ => {
|
_ => {
|
||||||
::yaserde::__derive_trace!("SKIPPINGSKIPPING Skipping element {:?}", name.local_name);
|
|
||||||
return Err(format!("Found unauthorized element {}", name.local_name));
|
|
||||||
|
|
||||||
let event = reader.next_event()?;
|
let event = reader.next_event()?;
|
||||||
#write_unused
|
#write_unused
|
||||||
|
|
||||||
@ -501,10 +480,8 @@ fn build_call_visitor(
|
|||||||
quote!(name.local_name.as_str()),
|
quote!(name.local_name.as_str()),
|
||||||
);
|
);
|
||||||
|
|
||||||
let namespace = field.prefix_namespace(root_attributes);
|
|
||||||
|
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
(#namespace, #label_name) => {
|
#label_name => {
|
||||||
let visitor = #visitor_label{};
|
let visitor = #visitor_label{};
|
||||||
|
|
||||||
#namespaces_matching
|
#namespaces_matching
|
||||||
|
|||||||
@ -10,34 +10,21 @@ pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result<TokenStream,
|
|||||||
let name = &ast.ident;
|
let name = &ast.ident;
|
||||||
let attrs = &ast.attrs;
|
let attrs = &ast.attrs;
|
||||||
let data = &ast.data;
|
let data = &ast.data;
|
||||||
let generics = &ast.generics;
|
|
||||||
|
|
||||||
let root_attributes = YaSerdeAttribute::parse(attrs);
|
let root_attributes = YaSerdeAttribute::parse(attrs);
|
||||||
|
|
||||||
let root_name = root_attributes.xml_element_name(name);
|
let root_name = format!(
|
||||||
let root_namespace = root_attributes
|
"{}{}",
|
||||||
.namespaces
|
root_attributes.prefix_namespace(),
|
||||||
.iter()
|
root_attributes.xml_element_name(name)
|
||||||
.find_map(|(prefix, namespace)| {
|
);
|
||||||
if root_attributes.prefix.eq(prefix) {
|
|
||||||
Some(namespace.clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let impl_block = match *data {
|
let impl_block = match *data {
|
||||||
syn::Data::Struct(ref data_struct) => expand_struct::parse(
|
syn::Data::Struct(ref data_struct) => {
|
||||||
data_struct,
|
expand_struct::parse(data_struct, name, &root_name, &root_attributes)
|
||||||
name,
|
}
|
||||||
&root_namespace,
|
|
||||||
&root_name,
|
|
||||||
&root_attributes,
|
|
||||||
generics,
|
|
||||||
),
|
|
||||||
syn::Data::Enum(ref data_enum) => {
|
syn::Data::Enum(ref data_enum) => {
|
||||||
expand_enum::parse(data_enum, name, &root_name, &root_attributes, generics)
|
expand_enum::parse(data_enum, name, &root_name, &root_attributes)
|
||||||
}
|
}
|
||||||
syn::Data::Union(ref _data_union) => unimplemented!(),
|
syn::Data::Union(ref _data_union) => unimplemented!(),
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,13 +5,9 @@ extern crate proc_macro;
|
|||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
mod de;
|
mod de;
|
||||||
mod primitives;
|
|
||||||
mod ser;
|
mod ser;
|
||||||
|
|
||||||
use primitives::{hexbinary_serde, primitive_serde, primitive_yaserde};
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use proc_macro2::TokenStream as TokenStream2;
|
|
||||||
use quote::quote;
|
|
||||||
|
|
||||||
#[proc_macro_derive(YaDeserialize, attributes(yaserde))]
|
#[proc_macro_derive(YaDeserialize, attributes(yaserde))]
|
||||||
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
||||||
@ -30,37 +26,3 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
|||||||
Err(msg) => panic!("{}", msg),
|
Err(msg) => panic!("{}", msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serialize & Deserialize a struct using it's UpperHex implementation
|
|
||||||
#[proc_macro_derive(HexBinaryYaSerde)]
|
|
||||||
pub fn derive_hexbinary(input: TokenStream) -> TokenStream {
|
|
||||||
let serde: TokenStream2 = hexbinary_serde(input.clone()).into();
|
|
||||||
let yaserde: TokenStream2 = primitive_yaserde(input).into();
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
use ::std::str::FromStr as _;
|
|
||||||
#serde
|
|
||||||
#yaserde
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serialize & Deserialize a primitive newtype by generating a FromStr & Display implementation
|
|
||||||
#[proc_macro_derive(PrimitiveYaSerde)]
|
|
||||||
pub fn derive_primitive(input: TokenStream) -> TokenStream {
|
|
||||||
let serde: TokenStream2 = primitive_serde(input.clone()).into();
|
|
||||||
let yaserde: TokenStream2 = primitive_yaserde(input).into();
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
use ::std::str::FromStr as _;
|
|
||||||
#serde
|
|
||||||
#yaserde
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serialize & Deserialize a type using it's existing FromStr & Display implementation
|
|
||||||
#[proc_macro_derive(DefaultYaSerde)]
|
|
||||||
pub fn derive_default(input: TokenStream) -> TokenStream {
|
|
||||||
primitive_yaserde(input)
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,118 +0,0 @@
|
|||||||
// Adds YaSerialize and YaDeserialize implementations for types that support FromStr and Display traits.
|
|
||||||
// Code originally from `xsd-parser-rs`
|
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
|
||||||
use proc_macro2::TokenStream as TokenStream2;
|
|
||||||
use quote::quote;
|
|
||||||
use syn::{parse_macro_input, DeriveInput};
|
|
||||||
|
|
||||||
pub fn primitive_yaserde(input: TokenStream) -> TokenStream {
|
|
||||||
let ast = parse_macro_input!(input as DeriveInput);
|
|
||||||
|
|
||||||
let struct_name = &ast.ident;
|
|
||||||
let struct_name_literal = &ast.ident.to_string();
|
|
||||||
|
|
||||||
let serde = quote! {
|
|
||||||
impl ::yaserde::YaSerialize for #struct_name {
|
|
||||||
fn serialize<W: ::std::io::Write>(
|
|
||||||
&self,
|
|
||||||
writer: &mut ::yaserde::ser::Serializer<W>,
|
|
||||||
) -> ::std::result::Result<(), ::std::string::String> {
|
|
||||||
::yaserde::primitives::serialize_primitives(
|
|
||||||
self,
|
|
||||||
#struct_name_literal,
|
|
||||||
writer, |s| s.to_string(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_attributes(
|
|
||||||
&self,
|
|
||||||
attributes: ::std::vec::Vec<::yaserde::__xml::attribute::OwnedAttribute>,
|
|
||||||
namespace: ::yaserde::__xml::namespace::Namespace,
|
|
||||||
) -> ::std::result::Result<
|
|
||||||
(
|
|
||||||
::std::vec::Vec<::yaserde::__xml::attribute::OwnedAttribute>,
|
|
||||||
::yaserde::__xml::namespace::Namespace,
|
|
||||||
),
|
|
||||||
::std::string::String,
|
|
||||||
> {
|
|
||||||
Ok((attributes, namespace))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::yaserde::YaDeserialize for #struct_name {
|
|
||||||
fn deserialize<R: ::std::io::Read>(
|
|
||||||
reader: &mut ::yaserde::de::Deserializer<R>,
|
|
||||||
) -> ::std::result::Result<Self, ::std::string::String> {
|
|
||||||
::yaserde::primitives::deserialize_primitives(
|
|
||||||
reader,
|
|
||||||
|s| #struct_name::from_str(s).map_err(|e| e.to_string()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
serde.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn hexbinary_serde(input: TokenStream) -> TokenStream {
|
|
||||||
let first = input.clone();
|
|
||||||
let DeriveInput { ident, .. } = parse_macro_input!(first);
|
|
||||||
// Calculate number digits to determine whether leading zero should be added
|
|
||||||
quote! {
|
|
||||||
impl std::fmt::Display for #ident {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{:02X}", self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::str::FromStr for #ident {
|
|
||||||
type Err = ::std::string::String;
|
|
||||||
|
|
||||||
fn from_str(s: &::std::primitive::str) -> ::std::result::Result<Self, Self::Err> {
|
|
||||||
Self::from_bits(
|
|
||||||
s.parse()
|
|
||||||
.map_err(|_| String::from("Failed to parse Bitflag integer"))?,
|
|
||||||
)
|
|
||||||
.ok_or(String::from("Unknown bits were set in Bitflag"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn primitive_serde(input: TokenStream) -> TokenStream {
|
|
||||||
let first = input.clone();
|
|
||||||
let ref di @ DeriveInput { ref ident, .. } = parse_macro_input!(first);
|
|
||||||
let fromstr = extract_full_path(di).unwrap();
|
|
||||||
quote! {
|
|
||||||
impl std::fmt::Display for #ident {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{}", self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::str::FromStr for #ident {
|
|
||||||
type Err = ::std::string::String;
|
|
||||||
|
|
||||||
fn from_str(s: &::std::primitive::str) -> ::std::result::Result<Self, Self::Err> {
|
|
||||||
Ok(#ident(#fromstr))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract_full_path(ast: &syn::DeriveInput) -> Result<TokenStream2, syn::Error> {
|
|
||||||
if let syn::Data::Struct(data_struct) = &ast.data {
|
|
||||||
if let syn::Fields::Unnamed(fields) = &data_struct.fields {
|
|
||||||
if let Some(syn::Type::Path(path)) = &fields.unnamed.first().map(|f| &f.ty) {
|
|
||||||
return Ok(
|
|
||||||
quote! { <#path as ::std::str::FromStr>::from_str(s).map_err(|e| e.to_string())? },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(syn::Error::new_spanned(ast, "Unable to extract full path"))
|
|
||||||
}
|
|
||||||
@ -2,16 +2,15 @@ use crate::common::{Field, YaSerdeAttribute, YaSerdeField};
|
|||||||
use crate::ser::{implement_serializer::implement_serializer, label::build_label_name};
|
use crate::ser::{implement_serializer::implement_serializer, label::build_label_name};
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
use syn::DataEnum;
|
||||||
use syn::Fields;
|
use syn::Fields;
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
use syn::{DataEnum, Generics};
|
|
||||||
|
|
||||||
pub fn serialize(
|
pub fn serialize(
|
||||||
data_enum: &DataEnum,
|
data_enum: &DataEnum,
|
||||||
name: &Ident,
|
name: &Ident,
|
||||||
root: &str,
|
root: &str,
|
||||||
root_attributes: &YaSerdeAttribute,
|
root_attributes: &YaSerdeAttribute,
|
||||||
generics: &Generics,
|
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let inner_enum_inspector = inner_enum_inspector(data_enum, name, root_attributes);
|
let inner_enum_inspector = inner_enum_inspector(data_enum, name, root_attributes);
|
||||||
|
|
||||||
@ -109,7 +108,6 @@ pub fn serialize(
|
|||||||
quote!(match self {
|
quote!(match self {
|
||||||
#inner_enum_inspector
|
#inner_enum_inspector
|
||||||
}),
|
}),
|
||||||
generics,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,15 +3,14 @@ use crate::common::{Field, YaSerdeAttribute, YaSerdeField};
|
|||||||
use crate::ser::{element::*, implement_serializer::implement_serializer};
|
use crate::ser::{element::*, implement_serializer::implement_serializer};
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
use syn::DataStruct;
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
use syn::{DataStruct, Generics};
|
|
||||||
|
|
||||||
pub fn serialize(
|
pub fn serialize(
|
||||||
data_struct: &DataStruct,
|
data_struct: &DataStruct,
|
||||||
name: &Ident,
|
name: &Ident,
|
||||||
root: &str,
|
root: &str,
|
||||||
root_attributes: &YaSerdeAttribute,
|
root_attributes: &YaSerdeAttribute,
|
||||||
generics: &Generics,
|
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let append_attributes: TokenStream = data_struct
|
let append_attributes: TokenStream = data_struct
|
||||||
.fields
|
.fields
|
||||||
@ -349,6 +348,5 @@ pub fn serialize(
|
|||||||
root_attributes,
|
root_attributes,
|
||||||
append_attributes,
|
append_attributes,
|
||||||
struct_inspector,
|
struct_inspector,
|
||||||
generics,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ use crate::ser::namespace::generate_namespaces_definition;
|
|||||||
use proc_macro2::Ident;
|
use proc_macro2::Ident;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::Generics;
|
|
||||||
|
|
||||||
pub fn implement_serializer(
|
pub fn implement_serializer(
|
||||||
name: &Ident,
|
name: &Ident,
|
||||||
@ -11,15 +10,12 @@ pub fn implement_serializer(
|
|||||||
attributes: &YaSerdeAttribute,
|
attributes: &YaSerdeAttribute,
|
||||||
append_attributes: TokenStream,
|
append_attributes: TokenStream,
|
||||||
inner_inspector: TokenStream,
|
inner_inspector: TokenStream,
|
||||||
generics: &Generics,
|
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let namespaces_definition = generate_namespaces_definition(attributes);
|
let namespaces_definition = generate_namespaces_definition(attributes);
|
||||||
let flatten = attributes.flatten;
|
let flatten = attributes.flatten;
|
||||||
|
|
||||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
impl #impl_generics ::yaserde::YaSerialize for #name #ty_generics #where_clause {
|
impl ::yaserde::YaSerialize for #name {
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn serialize<W: ::std::io::Write>(
|
fn serialize<W: ::std::io::Write>(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@ -13,7 +13,6 @@ pub fn expand_derive_serialize(ast: &syn::DeriveInput) -> Result<TokenStream, St
|
|||||||
let name = &ast.ident;
|
let name = &ast.ident;
|
||||||
let attrs = &ast.attrs;
|
let attrs = &ast.attrs;
|
||||||
let data = &ast.data;
|
let data = &ast.data;
|
||||||
let generics = &ast.generics;
|
|
||||||
|
|
||||||
let root_attributes = YaSerdeAttribute::parse(attrs);
|
let root_attributes = YaSerdeAttribute::parse(attrs);
|
||||||
|
|
||||||
@ -25,10 +24,10 @@ pub fn expand_derive_serialize(ast: &syn::DeriveInput) -> Result<TokenStream, St
|
|||||||
|
|
||||||
let impl_block = match *data {
|
let impl_block = match *data {
|
||||||
syn::Data::Struct(ref data_struct) => {
|
syn::Data::Struct(ref data_struct) => {
|
||||||
expand_struct::serialize(data_struct, name, &root_name, &root_attributes, generics)
|
expand_struct::serialize(data_struct, name, &root_name, &root_attributes)
|
||||||
}
|
}
|
||||||
syn::Data::Enum(ref data_enum) => {
|
syn::Data::Enum(ref data_enum) => {
|
||||||
expand_enum::serialize(data_enum, name, &root_name, &root_attributes, generics)
|
expand_enum::serialize(data_enum, name, &root_name, &root_attributes)
|
||||||
}
|
}
|
||||||
syn::Data::Union(ref _data_union) => unimplemented!(),
|
syn::Data::Union(ref _data_union) => unimplemented!(),
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user