serde_struct_tuple_enum/
lib.rs

1//! # serde-struct-tuple-enum
2//!
3//! **serde-struct-tuple-enum** 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 enum types, where each variant of the enum is a struct that is encoded as a tuple of its fields (specifically using [`serde-struct-tuple`](https://crates.io/crates/serde-struct-tuple)).
4//!
5//! Enums are expected to consist only of unit variants, wrapping a struct that implements
6//! `serde_struct_tuple::SerializeStructTuple` and `serde_struct_tuple::DeserializeStructTuple`
7//! (likely by using the corresponding derive macros).
8//!
9//! Each enum variant gets a single "tag" that is encoded as the first element in the tuple. This
10//! tag allows the enum variant to be selected for deserializing the rest of the tuple.
11//!
12//! This message format directly corresponds to how [WAMP](https://wamp-proto.org/spec.html) messages are encoded.
13//!
14//! ## Example
15//! ```
16//! use std::collections::BTreeMap;
17//!
18//! use serde_struct_tuple::{
19//!     DeserializeStructTuple,
20//!     SerializeStructTuple,
21//! };
22//! use serde_struct_tuple_enum::{
23//!     DeserializeStructTupleEnum,
24//!     SerializeStructTupleEnum,
25//! };
26//!
27//! #[derive(Debug, Default, PartialEq, Eq, SerializeStructTuple, DeserializeStructTuple)]
28//! struct Foo {
29//!     a: u64,
30//!     b: bool,
31//!     #[serde_struct_tuple(default, skip_serializing_if = Vec::is_empty)]
32//!     c: Vec<u64>,
33//! }
34//!
35//! #[derive(Debug, Default, PartialEq, Eq, SerializeStructTuple, DeserializeStructTuple)]
36//! struct Bar {
37//!     a: String,
38//!     #[serde_struct_tuple(default, skip_serializing_if = BTreeMap::is_empty)]
39//!     b: BTreeMap<u64, u64>,
40//! }
41//!
42//! #[derive(Debug, PartialEq, Eq, SerializeStructTupleEnum, DeserializeStructTupleEnum)]
43//! #[tag(u64)]
44//! enum Message {
45//!     #[tag = 1]
46//!     Foo(Foo),
47//!     #[tag = 2]
48//!     Bar(Bar),
49//! }
50//!
51//! fn main() {
52//!     // Serialization.
53//!     assert_eq!(
54//!         serde_json::to_string(&Message::Foo(Foo {
55//!             a: 123,
56//!             b: true,
57//!             c: Vec::from_iter([7, 8, 9]),
58//!         }))
59//!         .unwrap(),
60//!         r#"[1,123,true,[7,8,9]]"#
61//!     );
62//!     assert_eq!(
63//!         serde_json::to_string(&Message::Bar(Bar {
64//!             a: "hello".to_owned(),
65//!             b: BTreeMap::from_iter([(3, 6), (4, 8)]),
66//!         }))
67//!         .unwrap(),
68//!         r#"[2,"hello",{"3":6,"4":8}]"#
69//!     );
70//!
71//!     // Deserialization.
72//!     assert_eq!(
73//!         serde_json::from_str::<Message>(r#"[1,1000,false]"#).unwrap(),
74//!         Message::Foo(Foo {
75//!             a: 1000,
76//!             b: false,
77//!             ..Default::default()
78//!         })
79//!     );
80//!     assert_eq!(
81//!         serde_json::from_str::<Message>(r#"[2,"goodbye",{"1":2,"3":4}]"#).unwrap(),
82//!         Message::Bar(Bar {
83//!             a: "goodbye".to_owned(),
84//!             b: BTreeMap::from_iter([(1, 2), (3, 4)]),
85//!         })
86//!     );
87//!     assert!(
88//!         serde_json::from_str::<Message>(r#"[3]"#)
89//!             .unwrap_err()
90//!             .to_string()
91//!             .contains("expected Message tuple")
92//!     );
93//! }
94//! ```
95
96pub use serde_struct_tuple_enum_proc_macro::{
97    DeserializeStructTupleEnum,
98    SerializeStructTupleEnum,
99};