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}