add floating point de/ser-ialization

This commit is contained in:
Marc-Antoine Arnaud 2018-05-28 17:40:00 +02:00
parent e3cd73b32e
commit ef37615458
7 changed files with 121 additions and 59 deletions

View File

@ -60,6 +60,14 @@ pub trait Visitor<'de>: Sized {
Err(format!("Unexpected u64 {:?}", v))
}
fn visit_f32(self, v: &str) -> Result<Self::Value, String> {
Err(format!("Unexpected f32 {:?}", v))
}
fn visit_f64(self, v: &str) -> Result<Self::Value, String> {
Err(format!("Unexpected f64 {:?}", v))
}
fn visit_str(self, v: &str) -> Result<Self::Value, String> {
Err(format!("Unexpected str {:?}", v))
}

View File

@ -61,6 +61,8 @@ 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!(f32, -12.5_f32 as f32, "-12.5");
convert_and_validate!(f64, -12.5 as f64, "-12.5");
convert_and_validate_for_attribute!(bool, true, "true");
convert_and_validate_for_attribute!(u8, 12 as u8, "12");
@ -75,4 +77,6 @@ fn de_type() {
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");
convert_and_validate_for_attribute!(f32, -12.5 as f32, "-12.5");
convert_and_validate_for_attribute!(f64, -12.5 as f64, "-12.5");
}

View File

@ -57,6 +57,8 @@ 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!(f32, -12.5 as f32, "-12.5");
convert_and_validate!(f64, -12.5 as f64, "-12.5");
convert_and_validate_as_attribute!(bool, true, "true");
convert_and_validate_as_attribute!(u8, 12 as u8, "12");
@ -71,4 +73,6 @@ fn ser_type() {
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");
convert_and_validate_as_attribute!(f32, -12.5 as f32, "-12.5");
convert_and_validate_as_attribute!(f64, -12.5 as f64, "-12.5");
}

View File

@ -56,6 +56,12 @@ pub fn parse(
Some(FieldType::FieldTypeU64) => {
build_default_value(field_label, &quote!{u64}, &quote!{0})
}
Some(FieldType::FieldTypeF32) => {
build_default_value(field_label, &quote!{f32}, &quote!{0})
}
Some(FieldType::FieldTypeF64) => {
build_default_value(field_label, &quote!{f64}, &quote!{0})
}
Some(FieldType::FieldTypeStruct { struct_name }) => Some(quote!{
#[allow(unused_mut)]
let mut #field_label : #struct_name = #struct_name::default();
@ -93,6 +99,12 @@ pub fn parse(
Some(&FieldType::FieldTypeU64) => {
build_default_value(field_label, &quote!{Vec<u64>}, &quote!{vec![]})
}
Some(&FieldType::FieldTypeF32) => {
build_default_value(field_label, &quote!{Vec<f32>}, &quote!{vec![]})
}
Some(&FieldType::FieldTypeF64) => {
build_default_value(field_label, &quote!{Vec<f64>}, &quote!{vec![]})
}
Some(&FieldType::FieldTypeStruct { ref struct_name }) => Some(quote!{
#[allow(unused_mut)]
let mut #field_label : Vec<#struct_name> = vec![];
@ -128,61 +140,6 @@ pub fn parse(
sum
});
let enum_visitors: TokenStream = data_enum
.variants
.iter()
.map(|variant| {
match variant.fields {
Fields::Unit => None,
Fields::Named(ref fields) => {
let enum_fields = fields
.named
.iter()
.map(|field| {
// let label = field.ident;
// let label_name = label.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!{
// struct #visitor_label;
// impl<'de> Visitor<'de> for #visitor_label {
// type Value = String;
// fn visit_str(self, v: &str) -> Result<Self::Value, String> {
// match v {
// _ => Err("unable to match \"{}\" with enum {}", v, #label_name)
// }
// Ok(String::from(v))
// }
// }
})
}
_ => None,
}
})
.filter(|x| x.is_some())
.map(|x| x.unwrap())
.fold(TokenStream::empty(), |mut sum, val| {
sum.append_all(val);
sum
});
Some(enum_fields)
}
Fields::Unnamed(ref _fields) => {
unimplemented!();
}
}
})
.filter(|x| x.is_some())
.map(|x| x.unwrap())
.fold(TokenStream::empty(), |mut sum, val| {
sum.append_all(val);
sum
});
let match_to_enum: TokenStream = data_enum
.variants
.iter()
@ -229,7 +186,6 @@ pub fn parse(
let mut simple_enum_value = None;
#variables
#enum_visitors
loop {
match reader.peek()?.to_owned() {

View File

@ -56,6 +56,8 @@ pub fn parse(
Some(FieldType::FieldTypeU32) => build_default_value(label, &quote!{u32}, &quote!{0}),
Some(FieldType::FieldTypeI64) => build_default_value(label, &quote!{i64}, &quote!{0}),
Some(FieldType::FieldTypeU64) => build_default_value(label, &quote!{u64}, &quote!{0}),
Some(FieldType::FieldTypeF32) => build_default_value(label, &quote!{f32}, &quote!{0.0}),
Some(FieldType::FieldTypeF64) => build_default_value(label, &quote!{f64}, &quote!{0.0}),
Some(FieldType::FieldTypeStruct { struct_name }) => Some(quote!{
#[allow(unused_mut, non_snake_case, non_camel_case_types)]
let mut #label : #struct_name = #struct_name::default();
@ -93,6 +95,12 @@ pub fn parse(
Some(&FieldType::FieldTypeU64) => {
build_default_value(label, &quote!{Vec<u64>}, &quote!{vec![]})
}
Some(&FieldType::FieldTypeF32) => {
build_default_value(label, &quote!{Vec<f32>}, &quote!{vec![]})
}
Some(&FieldType::FieldTypeF64) => {
build_default_value(label, &quote!{Vec<f64>}, &quote!{vec![]})
}
Some(&FieldType::FieldTypeStruct { ref struct_name }) => Some(quote!{
#[allow(unused_mut)]
let mut #label : Vec<#struct_name> = vec![];
@ -159,6 +167,12 @@ pub fn parse(
Some(FieldType::FieldTypeU64) => {
build_declare_visitor(&quote!{u64}, &quote!{visit_u64}, &visitor_label)
}
Some(FieldType::FieldTypeF32) => {
build_declare_visitor(&quote!{f32}, &quote!{visit_f32}, &visitor_label)
}
Some(FieldType::FieldTypeF64) => {
build_declare_visitor(&quote!{f64}, &quote!{visit_f64}, &visitor_label)
}
Some(FieldType::FieldTypeStruct { struct_name }) => {
let struct_id = struct_name.to_string();
let struct_ident = Ident::new(
@ -213,6 +227,12 @@ pub fn parse(
Some(&FieldType::FieldTypeU64) => {
build_declare_visitor(&quote!{u64}, &quote!{visit_u64}, &visitor_label)
}
Some(&FieldType::FieldTypeF32) => {
build_declare_visitor(&quote!{f32}, &quote!{visit_f32}, &visitor_label)
}
Some(&FieldType::FieldTypeF64) => {
build_declare_visitor(&quote!{f64}, &quote!{visit_f64}, &visitor_label)
}
Some(&FieldType::FieldTypeStruct { ref struct_name }) => {
let struct_ident = Ident::new(&format!("{}", struct_name), Span::call_site());
Some(quote!{
@ -366,6 +386,28 @@ pub fn parse(
&label_name,
)
}
Some(FieldType::FieldTypeF32) => {
let visitor = Ident::new("visit_f32", Span::call_site());
build_call_visitor(
&quote!{f32},
&visitor,
&quote!{= value},
&visitor_label,
label,
&label_name,
)
}
Some(FieldType::FieldTypeF64) => {
let visitor = Ident::new("visit_f64", Span::call_site());
build_call_visitor(
&quote!{f64},
&visitor,
&quote!{= value},
&visitor_label,
label,
&label_name,
)
}
Some(FieldType::FieldTypeStruct { struct_name }) => Some(quote!{
#label_name => {
reader.set_map_value();
@ -493,6 +535,28 @@ pub fn parse(
&label_name,
)
}
Some(&FieldType::FieldTypeF32) => {
let visitor = Ident::new("visit_f32", Span::call_site());
build_call_visitor(
&quote!{f32},
&visitor,
&quote!{.push(value)},
&visitor_label,
label,
&label_name,
)
}
Some(&FieldType::FieldTypeF64) => {
let visitor = Ident::new("visit_f64", Span::call_site());
build_call_visitor(
&quote!{f64},
&visitor,
&quote!{.push(value)},
&visitor_label,
label,
&label_name,
)
}
Some(&FieldType::FieldTypeStruct { ref struct_name }) => {
let struct_ident = Ident::new(&format!("{}", struct_name), Span::call_site());
Some(quote!{
@ -576,6 +640,12 @@ pub fn parse(
Some(FieldType::FieldTypeU64) => {
build_call_visitor_for_attribute(label, &label_name, &quote!{visit_u64}, &visitor_label)
}
Some(FieldType::FieldTypeF32) => {
build_call_visitor_for_attribute(label, &label_name, &quote!{visit_f32}, &visitor_label)
}
Some(FieldType::FieldTypeF64) => {
build_call_visitor_for_attribute(label, &label_name, &quote!{visit_f64}, &visitor_label)
}
Some(FieldType::FieldTypeStruct { struct_name }) => {
let struct_ident = Ident::new(
@ -661,6 +731,16 @@ pub fn parse(
label,
&quote!{u64::from_str(text_content).unwrap()},
),
Some(FieldType::FieldTypeF32) => build_set_text_to_value(
&field_attrs,
label,
&quote!{f32::from_str(text_content).unwrap()},
),
Some(FieldType::FieldTypeF64) => build_set_text_to_value(
&field_attrs,
label,
&quote!{f64::from_str(text_content).unwrap()},
),
Some(FieldType::FieldTypeStruct { .. }) | Some(FieldType::FieldTypeVec { .. }) | None => {
None

View File

@ -14,6 +14,8 @@ pub enum FieldType {
FieldTypeU32,
FieldTypeI64,
FieldTypeU64,
FieldTypeF32,
FieldTypeF64,
FieldTypeVec { data_type: Box<FieldType> },
FieldTypeStruct { struct_name: syn::Ident },
}
@ -31,6 +33,8 @@ impl FieldType {
"u32" => Some(FieldType::FieldTypeU32),
"i64" => Some(FieldType::FieldTypeI64),
"u64" => Some(FieldType::FieldTypeU64),
"f32" => Some(FieldType::FieldTypeF32),
"f64" => Some(FieldType::FieldTypeF64),
"Vec" => get_vec_type(t).map(|data_type| {
let p = syn::PathSegment {
ident: data_type,

View File

@ -43,7 +43,9 @@ pub fn serialize(
| Some(FieldType::FieldTypeI32)
| Some(FieldType::FieldTypeU32)
| Some(FieldType::FieldTypeI64)
| Some(FieldType::FieldTypeU64) => Some(quote!{
| Some(FieldType::FieldTypeU64)
| Some(FieldType::FieldTypeF32)
| Some(FieldType::FieldTypeF64) => Some(quote!{
.attr(#label_name, &*{
use std::mem;
unsafe {
@ -141,7 +143,9 @@ pub fn serialize(
| Some(FieldType::FieldTypeI32)
| Some(FieldType::FieldTypeU32)
| Some(FieldType::FieldTypeI64)
| Some(FieldType::FieldTypeU64) => Some(quote!{
| Some(FieldType::FieldTypeU64)
| Some(FieldType::FieldTypeF32)
| Some(FieldType::FieldTypeF64) => Some(quote!{
let start_event = XmlEvent::start_element(#label_name);
let _ret = writer.write(start_event);
@ -184,7 +188,9 @@ pub fn serialize(
| Some(&FieldType::FieldTypeI32)
| Some(&FieldType::FieldTypeU32)
| Some(&FieldType::FieldTypeI64)
| Some(&FieldType::FieldTypeU64) => Some(quote!{
| Some(&FieldType::FieldTypeU64)
| Some(&FieldType::FieldTypeF32)
| Some(&FieldType::FieldTypeF64) => Some(quote!{
for item in &self.#label {
let start_event = XmlEvent::start_element(#label_name);
let _ret = writer.write(start_event);