serde_struct_tuple/
lib.rs

1//! # serde-struct-tuple
2//!
3//! **serde-struct-tuple** is a utility crate, built initially for [`battler-wamp`](https://crates.io/crates/battler-wamp). It provides procedural macros to automatically derive [`serde`](https://serde.rs/)'s `Serialize` and `Deserialize` traits for struct types that should be encoded as a tuple (list) of its fields.
4//!
5//! Struct fields can be any type that implement `serde::Serialize` and/or `serde::Deserialize`.
6//!
7//! The macro also has additional optional attributes for struct fields:
8//!
9//! * `default` - If the field is missing during deserialization, the field is initialized to its
10//!   default value.
11//! * `skip_serializing_if` - Checks if the field should be skipped during serialization using the
12//!   function provided. All subsequent fields will also be skipped, regardless of their value.
13//!
14//! ## Example
15//!
16//! ```
17//! use std::collections::BTreeMap;
18//!
19//! use serde_struct_tuple::{
20//!     DeserializeStructTuple,
21//!     SerializeStructTuple,
22//! };
23//!
24//! fn is_true(b: &bool) -> bool {
25//!     *b
26//! }
27//!
28//! #[derive(Debug, Default, PartialEq, Eq, SerializeStructTuple, DeserializeStructTuple)]
29//! struct Message {
30//!     a: u64,
31//!     b: String,
32//!     #[serde_struct_tuple(default, skip_serializing_if = Vec::is_empty)]
33//!     c: Vec<u64>,
34//!     #[serde_struct_tuple(default, skip_serializing_if = BTreeMap::is_empty)]
35//!     d: BTreeMap<u8, bool>,
36//!     #[serde_struct_tuple(default, skip_serializing_if = is_true)]
37//!     e: bool,
38//! }
39//!
40//! fn main() {
41//!     // Serialization.
42//!     assert_eq!(
43//!         serde_json::to_string(&Message {
44//!             a: 123,
45//!             b: "foo".to_owned(),
46//!             ..Default::default()
47//!         })
48//!         .unwrap(),
49//!         r#"[123,"foo"]"#
50//!     );
51//!     assert_eq!(
52//!         serde_json::to_string(&Message {
53//!             a: 123,
54//!             b: "foo".to_owned(),
55//!             // Skipped because `c` is skipped.
56//!             d: BTreeMap::from_iter([(1, false), (2, true)]),
57//!             ..Default::default()
58//!         })
59//!         .unwrap(),
60//!         r#"[123,"foo"]"#
61//!     );
62//!     assert_eq!(
63//!         serde_json::to_string(&Message {
64//!             a: 123,
65//!             b: "foo".to_owned(),
66//!             c: Vec::from_iter([6, 7, 8]),
67//!             d: BTreeMap::from_iter([(1, false), (2, true)]),
68//!             ..Default::default()
69//!         })
70//!         .unwrap(),
71//!         r#"[123,"foo",[6,7,8],{"1":false,"2":true},false]"#
72//!     );
73//!
74//!     // Deserialization.
75//!     assert_eq!(
76//!         serde_json::from_str::<Message>(r#"[123, "foo"]"#).unwrap(),
77//!         Message {
78//!             a: 123,
79//!             b: "foo".to_owned(),
80//!             ..Default::default()
81//!         }
82//!     );
83//!     assert_eq!(
84//!         serde_json::from_str::<Message>(r#"[123, "foo", [99, 100], { "20": true }, true]"#)
85//!             .unwrap(),
86//!         Message {
87//!             a: 123,
88//!             b: "foo".to_owned(),
89//!             c: Vec::from_iter([99, 100]),
90//!             d: BTreeMap::from_iter([(20, true)]),
91//!             e: true,
92//!         }
93//!     );
94//! }
95//! ```
96
97pub use serde_struct_tuple_proc_macro::{
98    DeserializeStructTuple,
99    SerializeStructTuple,
100};
101
102/// Trait for deserializing a struct from a tuple of its fields.
103pub trait DeserializeStructTuple {
104    type Value;
105
106    /// The [`serde::de::Visitor`] implementation that reads all fields from a sequence into the
107    /// struct.
108    fn visitor<'de>() -> impl serde::de::Visitor<'de, Value = Self::Value>;
109}
110
111/// Trait for serializing a struct into a tuple of its fields.
112pub trait SerializeStructTuple {
113    /// Serializes all struct fields to the given [`serde::ser::SerializeSeq`], in declaration
114    /// order.
115    fn serialize_fields_to_seq<S>(&self, seq: &mut S) -> core::result::Result<(), S::Error>
116    where
117        S: serde::ser::SerializeSeq;
118}