diff --git a/yaserde/tests/der_type.rs b/yaserde/tests/der_type.rs
index 5f19323..fc03f6c 100644
--- a/yaserde/tests/der_type.rs
+++ b/yaserde/tests/der_type.rs
@@ -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("";
+
+ let loaded: Result = from_str(&content);
+ assert_eq!(loaded, Ok(model));
+ }};
+}
+
#[test]
fn de_type() {
convert_and_validate!(bool, true, "true");
@@ -42,4 +61,18 @@ fn de_type() {
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_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");
}
diff --git a/yaserde/tests/se_type.rs b/yaserde/tests/se_type.rs
index 347a3a6..bd337c3 100644
--- a/yaserde/tests/se_type.rs
+++ b/yaserde/tests/se_type.rs
@@ -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 = to_string(&model);
+ let content = String::from("";
+ assert_eq!(data, Ok(content));
+ }};
+}
+
#[test]
fn ser_type() {
convert_and_validate!(bool, true, "true");
@@ -40,4 +57,18 @@ fn ser_type() {
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_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");
}
diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs
index 9f876a7..7a87fcb 100644
--- a/yaserde_derive/src/de/expand_struct.rs
+++ b/yaserde_derive/src/de/expand_struct.rs
@@ -559,6 +559,8 @@ pub fn parse(
field.ident.unwrap().to_string()
};
+ let visitor_label = Ident::new(&format!("__Visitor{}", label_name), Span::call_site());
+
match get_field_type(field) {
Some(FieldType::FieldTypeString) => Some(quote!{
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 }) => {
let struct_ident = Ident::new(
&format!("__Visitor_{}_{}", label_name, struct_name),
@@ -807,6 +819,25 @@ fn build_call_visitor(
})
}
+fn build_call_visitor_for_attribute(
+ label: &Option,
+ label_name: &str,
+ visitor: &Tokens,
+ visitor_label: &Ident,
+) -> Option {
+ 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(
field_attrs: &YaSerdeAttribute,
label: &Option,
diff --git a/yaserde_derive/src/ser/expand_struct.rs b/yaserde_derive/src/ser/expand_struct.rs
index 298a570..e6315c9 100644
--- a/yaserde_derive/src/ser/expand_struct.rs
+++ b/yaserde_derive/src/ser/expand_struct.rs
@@ -44,7 +44,16 @@ pub fn serialize(
| Some(FieldType::FieldTypeU32)
| Some(FieldType::FieldTypeI64)
| 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!{
.attr(#label_name, &*{