1use derive_more::From;
2use serde::{Deserialize, Serialize};
3
4#[derive(Clone, Debug, From, PartialEq, Eq, Serialize, Deserialize)]
6#[serde(untagged)]
7pub enum Msg<T> {
8 Single(T),
9 Batch(Vec<T>),
10}
11
12impl<T> Msg<T> {
13 #[inline]
15 pub fn single(payload: T) -> Self {
16 Self::Single(payload)
17 }
18
19 pub fn batch<I>(payloads: I) -> Self
21 where
22 I: IntoIterator<Item = T>,
23 {
24 Self::Batch(payloads.into_iter().collect())
25 }
26
27 #[inline]
29 pub fn is_single(&self) -> bool {
30 matches!(self, Self::Single(_))
31 }
32
33 #[inline]
35 pub fn as_single(&self) -> Option<&T> {
36 match self {
37 Self::Single(x) => Some(x),
38 _ => None,
39 }
40 }
41
42 #[inline]
44 pub fn as_mut_single(&mut self) -> Option<&T> {
45 match self {
46 Self::Single(x) => Some(x),
47 _ => None,
48 }
49 }
50
51 #[inline]
53 pub fn into_single(self) -> Option<T> {
54 match self {
55 Self::Single(x) => Some(x),
56 _ => None,
57 }
58 }
59
60 #[inline]
62 pub fn is_batch(&self) -> bool {
63 matches!(self, Self::Batch(_))
64 }
65
66 #[inline]
68 pub fn as_batch(&self) -> Option<&[T]> {
69 match self {
70 Self::Batch(x) => Some(x),
71 _ => None,
72 }
73 }
74
75 #[inline]
77 pub fn as_mut_batch(&mut self) -> Option<&mut [T]> {
78 match self {
79 Self::Batch(x) => Some(x),
80 _ => None,
81 }
82 }
83
84 #[inline]
86 pub fn into_batch(self) -> Option<Vec<T>> {
87 match self {
88 Self::Batch(x) => Some(x),
89 _ => None,
90 }
91 }
92
93 #[inline]
95 pub fn into_vec(self) -> Vec<T> {
96 match self {
97 Self::Single(x) => vec![x],
98 Self::Batch(x) => x,
99 }
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 mod single {
108 use super::*;
109
110 #[test]
111 fn should_be_able_to_serialize_to_json() {
112 let msg = Msg::single("hello world");
113
114 let value = serde_json::to_value(msg).unwrap();
115 assert_eq!(value, serde_json::json!("hello world"));
116 }
117
118 #[test]
119 fn should_be_able_to_deserialize_from_json() {
120 let value = serde_json::json!("hello world");
121
122 let msg: Msg<String> = serde_json::from_value(value).unwrap();
123 assert_eq!(msg, Msg::single(String::from("hello world")));
124 }
125
126 #[test]
127 fn should_be_able_to_serialize_to_msgpack() {
128 let msg = Msg::single("hello world");
129
130 let _ = rmp_serde::encode::to_vec_named(&msg).unwrap();
135 }
136
137 #[test]
138 fn should_be_able_to_deserialize_from_msgpack() {
139 let buf = rmp_serde::encode::to_vec_named(&Msg::single("hello world")).unwrap();
144
145 let msg: Msg<String> = rmp_serde::decode::from_slice(&buf).unwrap();
146 assert_eq!(msg, Msg::single(String::from("hello world")));
147 }
148 }
149
150 mod batch {
151 use super::*;
152
153 #[test]
154 fn should_be_able_to_serialize_to_json() {
155 let msg = Msg::batch(["hello world"]);
156
157 let value = serde_json::to_value(msg).unwrap();
158 assert_eq!(value, serde_json::json!(["hello world"]));
159 }
160
161 #[test]
162 fn should_be_able_to_deserialize_from_json() {
163 let value = serde_json::json!(["hello world"]);
164
165 let msg: Msg<String> = serde_json::from_value(value).unwrap();
166 assert_eq!(msg, Msg::batch([String::from("hello world")]));
167 }
168
169 #[test]
170 fn should_be_able_to_serialize_to_msgpack() {
171 let msg = Msg::batch(["hello world"]);
172
173 let _ = rmp_serde::encode::to_vec_named(&msg).unwrap();
178 }
179
180 #[test]
181 fn should_be_able_to_deserialize_from_msgpack() {
182 let buf = rmp_serde::encode::to_vec_named(&Msg::batch(["hello world"])).unwrap();
187
188 let msg: Msg<String> = rmp_serde::decode::from_slice(&buf).unwrap();
189 assert_eq!(msg, Msg::batch([String::from("hello world")]));
190 }
191 }
192}