Function serde_aux::deserialize_number_from_string [] [src]

pub fn deserialize_number_from_string<'de, T, D>(
    deserializer: D
) -> Result<T, D::Error> where
    D: Deserializer<'de>,
    T: FromStr + Deserialize<'de>,
    <T as FromStr>::Err: Display

Deserializes a number from string or a number.

Example:

#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate serde_aux;
extern crate serde;

#[derive(Serialize, Deserialize, Debug)]
struct MyStruct {
    #[serde(deserialize_with = "serde_aux::deserialize_number_from_string")]
    number_from_string: u64,
}
fn main() {
    // Note, the the current implementation does not check if it the original was not a number.
    let s = r#" { "number_from_string": "123" } "#;
    let a: MyStruct = serde_json::from_str(s).unwrap();
    assert_eq!(a.number_from_string, 123);

    let s = r#" { "number_from_string": 444 } "#;
    let a: MyStruct = serde_json::from_str(s).unwrap();
    assert_eq!(a.number_from_string, 444);
}

For making it work with strong types you must implement FromStr trait. It is quite simple:

#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate serde_aux;
extern crate serde;

use std::str::FromStr;
use std::num::{ParseIntError, ParseFloatError};

#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct IntId(u64);

impl FromStr for IntId {
    type Err = ParseIntError;

    fn from_str(s: &str) -> Result<IntId, Self::Err> {
        Ok(IntId(u64::from_str(s)?))
    }
}

#[derive(Serialize, Deserialize, Debug)]
struct MyStruct {
    #[serde(deserialize_with = "serde_aux::deserialize_number_from_string")]
    int_id: IntId,
}
fn main() {
    let s = r#"{ "int_id": "123" }"#;
    let a: MyStruct = serde_json::from_str(s).unwrap();
    assert_eq!(a.int_id.0, 123);

    let s = r#"{ "int_id": 444 }"#;
    let a: MyStruct = serde_json::from_str(s).unwrap();
    assert_eq!(a.int_id.0, 444);

}