Crate derive_serialize_into [] [src]

Custom derives SerializeInto, DeserializeFrom and DeserializeTryFrom.

If you have a type T: Serialize + Deserialize which can be converted to and from another type S, you can derive a Serialize implementation on it that converts to T before serialization, and a Deserialize implementation that deserializes to T and then converts to S. For the former, the requirement is that &T: Into<&S>, and for the latter it is S: Into<T>.

If S is a structure with a single field of type T, all you need is #[derive(SerializeInto, DeserializeFrom)]. Otherwise you have to specify the type T using #[serialize_into(T)] or #[deserialize_from(T)].

If S: TryInto<T> instead, possibly applying some validation, #[derive(DeserializeTryFrom)] will create a Deserialize implementation that fails even if deserialization into T succeds but conversion to S doesn't.

Finally, you can #[derive(IntoInner)] and #[derive(FromInner)] to avoid typing out the implementations for &S: From<&T> and T: From<S> by hand, if T is a single-field structure.

Example: simple wrapper types

#[macro_use]
extern crate derive_serialize_into;
extern crate serde;
extern crate serde_json;

#[derive(DeserializeFrom, FromInner, IntoInner, SerializeInto, Debug, Eq, PartialEq)]
struct Seconds(i64);

fn main() {
    assert_eq!(Seconds(5), serde_json::from_str("5").unwrap());
    assert_eq!("5", &serde_json::to_string(&Seconds(5)).unwrap());
    assert!(serde_json::from_str::<Seconds>("nan").is_err());
}

Example: validated email addresses

#[macro_use]
extern crate derive_serialize_into;
extern crate serde;
extern crate serde_json;
extern crate try_from;
extern crate validator;

#[derive(DeserializeTryFrom, IntoInner, SerializeInto, Debug, Eq, PartialEq)]
struct Email(String);

impl try_from::TryFrom<String> for Email {
    type Err = ();

    fn try_from(raw: String) -> Result<Email, ()> {
        if validator::validate_email(&raw) {
            Ok(Email(raw))
        } else {
            Err(())
        }
    }
}

fn main() {
    let email_json = r#""user@domain.com""#;
    let email = Email("user@domain.com".to_string());
    assert_eq!(email, serde_json::from_str(email_json).unwrap());
    assert_eq!(email_json, &serde_json::to_string(&email).unwrap());
    assert!(serde_json::from_str::<Email>(r#""missing_at_sign""#).is_err());
}

Functions

derive_deserialize_from
derive_deserialize_try_from
derive_from_inner
derive_into_inner
derive_serialize_into