#struct #tuple #serde #struct-fields #proc-macro

serde-struct-tuple

Procedural macro for deserializing a struct from a tuple of its fields

2 releases

0.1.1 Jan 19, 2025
0.1.0 Jan 1, 2025

#719 in Encoding

Download history 159/week @ 2024-12-31 26/week @ 2025-01-07 130/week @ 2025-01-14 38/week @ 2025-01-21

353 downloads per month
Used in 7 crates (2 directly)

MIT license

8KB

serde-struct-tuple

Latest Version

serde-struct-tuple is a utility crate, built initially for battler-wamp. It provides procedural macros to automatically derive serde's Serialize and Deserialize traits for struct types that should be encoded as a tuple (list) of its fields.


lib.rs:

serde-struct-tuple

serde-struct-tuple is a utility crate, built initially for battler-wamp. It provides procedural macros to automatically derive serde's Serialize and Deserialize traits for struct types that should be encoded as a tuple (list) of its fields.

Struct fields can be any type that implement serde::Serialize and/or serde::Deserialize.

The macro also has additional optional attributes for struct fields:

  • default - If the field is missing during deserialization, the field is initialized to its default value.
  • skip_serializing_if - Checks if the field should be skipped during serialization using the function provided. All subsequent fields will also be skipped, regardless of their value.

Example

use std::collections::BTreeMap;

use serde_struct_tuple::{
    DeserializeStructTuple,
    SerializeStructTuple,
};

fn is_true(b: &bool) -> bool {
    *b
}

#[derive(Debug, Default, PartialEq, Eq, SerializeStructTuple, DeserializeStructTuple)]
struct Message {
    a: u64,
    b: String,
    #[serde_struct_tuple(default, skip_serializing_if = Vec::is_empty)]
    c: Vec<u64>,
    #[serde_struct_tuple(default, skip_serializing_if = BTreeMap::is_empty)]
    d: BTreeMap<u8, bool>,
    #[serde_struct_tuple(default, skip_serializing_if = is_true)]
    e: bool,
}

fn main() {
    // Serialization.
    assert_eq!(
        serde_json::to_string(&Message {
            a: 123,
            b: "foo".to_owned(),
            ..Default::default()
        })
        .unwrap(),
        r#"[123,"foo"]"#
    );
    assert_eq!(
        serde_json::to_string(&Message {
            a: 123,
            b: "foo".to_owned(),
            // Skipped because `c` is skipped.
            d: BTreeMap::from_iter([(1, false), (2, true)]),
            ..Default::default()
        })
        .unwrap(),
        r#"[123,"foo"]"#
    );
    assert_eq!(
        serde_json::to_string(&Message {
            a: 123,
            b: "foo".to_owned(),
            c: Vec::from_iter([6, 7, 8]),
            d: BTreeMap::from_iter([(1, false), (2, true)]),
            ..Default::default()
        })
        .unwrap(),
        r#"[123,"foo",[6,7,8],{"1":false,"2":true},false]"#
    );

    // Deserialization.
    assert_eq!(
        serde_json::from_str::<Message>(r#"[123, "foo"]"#).unwrap(),
        Message {
            a: 123,
            b: "foo".to_owned(),
            ..Default::default()
        }
    );
    assert_eq!(
        serde_json::from_str::<Message>(r#"[123, "foo", [99, 100], { "20": true }, true]"#)
            .unwrap(),
        Message {
            a: 123,
            b: "foo".to_owned(),
            c: Vec::from_iter([99, 100]),
            d: BTreeMap::from_iter([(20, true)]),
            e: true,
        }
    );
}

Dependencies

~0.3–0.9MB
~21K SLoC