support type de/ser-ialization for attributes too
This commit is contained in:
parent
1101b2e16f
commit
98f1a0c146
@ -27,6 +27,25 @@ macro_rules! convert_and_validate {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! convert_and_validate_for_attribute {
|
||||||
|
($type: ty, $value: expr, $content: expr) => {{
|
||||||
|
#[derive(YaDeserialize, PartialEq, Debug)]
|
||||||
|
#[yaserde(root = "data")]
|
||||||
|
pub struct Data {
|
||||||
|
#[yaserde(attribute)]
|
||||||
|
item: $type,
|
||||||
|
}
|
||||||
|
|
||||||
|
let model = Data { item: $value };
|
||||||
|
|
||||||
|
let content = String::from("<?xml version=\"1.0\" encoding=\"utf-8\"?><data item=\"") + $content
|
||||||
|
+ "\" />";
|
||||||
|
|
||||||
|
let loaded: Result<Data, String> = from_str(&content);
|
||||||
|
assert_eq!(loaded, Ok(model));
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn de_type() {
|
fn de_type() {
|
||||||
convert_and_validate!(bool, true, "true");
|
convert_and_validate!(bool, true, "true");
|
||||||
@ -42,4 +61,18 @@ fn de_type() {
|
|||||||
convert_and_validate!(u64, 12 as u64, "12");
|
convert_and_validate!(u64, 12 as u64, "12");
|
||||||
convert_and_validate!(i64, 12 as i64, "12");
|
convert_and_validate!(i64, 12 as i64, "12");
|
||||||
convert_and_validate!(i64, -12 as i64, "-12");
|
convert_and_validate!(i64, -12 as i64, "-12");
|
||||||
|
|
||||||
|
convert_and_validate_for_attribute!(bool, true, "true");
|
||||||
|
convert_and_validate_for_attribute!(u8, 12 as u8, "12");
|
||||||
|
convert_and_validate_for_attribute!(i8, 12 as i8, "12");
|
||||||
|
convert_and_validate_for_attribute!(i8, -12 as i8, "-12");
|
||||||
|
convert_and_validate_for_attribute!(u16, 12 as u16, "12");
|
||||||
|
convert_and_validate_for_attribute!(i16, 12 as i16, "12");
|
||||||
|
convert_and_validate_for_attribute!(i16, -12 as i16, "-12");
|
||||||
|
convert_and_validate_for_attribute!(u32, 12 as u32, "12");
|
||||||
|
convert_and_validate_for_attribute!(i32, 12 as i32, "12");
|
||||||
|
convert_and_validate_for_attribute!(i32, -12 as i32, "-12");
|
||||||
|
convert_and_validate_for_attribute!(u64, 12 as u64, "12");
|
||||||
|
convert_and_validate_for_attribute!(i64, 12 as i64, "12");
|
||||||
|
convert_and_validate_for_attribute!(i64, -12 as i64, "-12");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,23 @@ macro_rules! convert_and_validate {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! convert_and_validate_as_attribute {
|
||||||
|
($type: ty, $value: expr, $content: expr) => {{
|
||||||
|
#[derive(YaSerialize, PartialEq, Debug)]
|
||||||
|
#[yaserde(root = "data")]
|
||||||
|
pub struct Data {
|
||||||
|
#[yaserde(attribute)]
|
||||||
|
item: $type,
|
||||||
|
}
|
||||||
|
let model = Data { item: $value };
|
||||||
|
|
||||||
|
let data: Result<String, String> = to_string(&model);
|
||||||
|
let content = String::from("<?xml version=\"1.0\" encoding=\"utf-8\"?><data item=\"") + $content
|
||||||
|
+ "\" />";
|
||||||
|
assert_eq!(data, Ok(content));
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ser_type() {
|
fn ser_type() {
|
||||||
convert_and_validate!(bool, true, "true");
|
convert_and_validate!(bool, true, "true");
|
||||||
@ -40,4 +57,18 @@ fn ser_type() {
|
|||||||
convert_and_validate!(u64, 12 as u64, "12");
|
convert_and_validate!(u64, 12 as u64, "12");
|
||||||
convert_and_validate!(i64, 12 as i64, "12");
|
convert_and_validate!(i64, 12 as i64, "12");
|
||||||
convert_and_validate!(i64, -12 as i64, "-12");
|
convert_and_validate!(i64, -12 as i64, "-12");
|
||||||
|
|
||||||
|
convert_and_validate_as_attribute!(bool, true, "true");
|
||||||
|
convert_and_validate_as_attribute!(u8, 12 as u8, "12");
|
||||||
|
convert_and_validate_as_attribute!(i8, 12 as i8, "12");
|
||||||
|
convert_and_validate_as_attribute!(i8, -12 as i8, "-12");
|
||||||
|
convert_and_validate_as_attribute!(u16, 12 as u16, "12");
|
||||||
|
convert_and_validate_as_attribute!(i16, 12 as i16, "12");
|
||||||
|
convert_and_validate_as_attribute!(i16, -12 as i16, "-12");
|
||||||
|
convert_and_validate_as_attribute!(u32, 12 as u32, "12");
|
||||||
|
convert_and_validate_as_attribute!(i32, 12 as i32, "12");
|
||||||
|
convert_and_validate_as_attribute!(i32, -12 as i32, "-12");
|
||||||
|
convert_and_validate_as_attribute!(u64, 12 as u64, "12");
|
||||||
|
convert_and_validate_as_attribute!(i64, 12 as i64, "12");
|
||||||
|
convert_and_validate_as_attribute!(i64, -12 as i64, "-12");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -559,6 +559,8 @@ pub fn parse(
|
|||||||
field.ident.unwrap().to_string()
|
field.ident.unwrap().to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let visitor_label = Ident::new(&format!("__Visitor{}", label_name), Span::call_site());
|
||||||
|
|
||||||
match get_field_type(field) {
|
match get_field_type(field) {
|
||||||
Some(FieldType::FieldTypeString) => Some(quote!{
|
Some(FieldType::FieldTypeString) => Some(quote!{
|
||||||
for attr in attributes {
|
for attr in attributes {
|
||||||
@ -567,6 +569,16 @@ pub fn parse(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
Some(FieldType::FieldTypeBool) => build_call_visitor_for_attribute(&label, &label_name, "e!{visit_bool}, &visitor_label),
|
||||||
|
Some(FieldType::FieldTypeI8) => build_call_visitor_for_attribute(&label, &label_name, "e!{visit_i8}, &visitor_label),
|
||||||
|
Some(FieldType::FieldTypeU8) => build_call_visitor_for_attribute(&label, &label_name, "e!{visit_u8}, &visitor_label),
|
||||||
|
Some(FieldType::FieldTypeI16) => build_call_visitor_for_attribute(&label, &label_name, "e!{visit_i16}, &visitor_label),
|
||||||
|
Some(FieldType::FieldTypeU16) => build_call_visitor_for_attribute(&label, &label_name, "e!{visit_u16}, &visitor_label),
|
||||||
|
Some(FieldType::FieldTypeI32) => build_call_visitor_for_attribute(&label, &label_name, "e!{visit_i32}, &visitor_label),
|
||||||
|
Some(FieldType::FieldTypeU32) => build_call_visitor_for_attribute(&label, &label_name, "e!{visit_u32}, &visitor_label),
|
||||||
|
Some(FieldType::FieldTypeI64) => build_call_visitor_for_attribute(&label, &label_name, "e!{visit_i64}, &visitor_label),
|
||||||
|
Some(FieldType::FieldTypeU64) => build_call_visitor_for_attribute(&label, &label_name, "e!{visit_u64}, &visitor_label),
|
||||||
|
|
||||||
Some(FieldType::FieldTypeStruct { struct_name }) => {
|
Some(FieldType::FieldTypeStruct { struct_name }) => {
|
||||||
let struct_ident = Ident::new(
|
let struct_ident = Ident::new(
|
||||||
&format!("__Visitor_{}_{}", label_name, struct_name),
|
&format!("__Visitor_{}_{}", label_name, struct_name),
|
||||||
@ -807,6 +819,25 @@ fn build_call_visitor(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_call_visitor_for_attribute(
|
||||||
|
label: &Option<Ident>,
|
||||||
|
label_name: &str,
|
||||||
|
visitor: &Tokens,
|
||||||
|
visitor_label: &Ident,
|
||||||
|
) -> Option<Tokens> {
|
||||||
|
Some(quote!{
|
||||||
|
for attr in attributes {
|
||||||
|
if attr.name.local_name == #label_name {
|
||||||
|
let visitor = #visitor_label{};
|
||||||
|
match visitor.#visitor(&attr.value) {
|
||||||
|
Ok(value) => {#label = value;}
|
||||||
|
Err(msg) => {return Err(msg);}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn build_set_text_to_value(
|
fn build_set_text_to_value(
|
||||||
field_attrs: &YaSerdeAttribute,
|
field_attrs: &YaSerdeAttribute,
|
||||||
label: &Option<Ident>,
|
label: &Option<Ident>,
|
||||||
|
|||||||
@ -44,7 +44,16 @@ pub fn serialize(
|
|||||||
| Some(FieldType::FieldTypeU32)
|
| Some(FieldType::FieldTypeU32)
|
||||||
| Some(FieldType::FieldTypeI64)
|
| Some(FieldType::FieldTypeI64)
|
||||||
| Some(FieldType::FieldTypeU64) => Some(quote!{
|
| Some(FieldType::FieldTypeU64) => Some(quote!{
|
||||||
.attr(#label_name, &self.#label)
|
.attr(#label_name, &*{
|
||||||
|
use std::mem;
|
||||||
|
unsafe {
|
||||||
|
let content = format!("{}", self.#label);
|
||||||
|
let ret : &'static str = mem::transmute(&content as &str);
|
||||||
|
mem::forget(content);
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
}),
|
}),
|
||||||
Some(FieldType::FieldTypeStruct { .. }) => Some(quote!{
|
Some(FieldType::FieldTypeStruct { .. }) => Some(quote!{
|
||||||
.attr(#label_name, &*{
|
.attr(#label_name, &*{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user