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};