1use std::collections::BTreeMap;
2
3use serde::{
4 ser::{Error as _, Impossible},
5 Serialize,
6};
7use serde_json::Value;
8
9pub struct AssertNamed<S>(pub S);
15
16macro_rules! unsupported_type {
17 ($expr:expr) => {{
18 let msg = concat!("unsupported type `", $expr, "`, expected a map");
19 match cfg!(debug_assertions) {
20 true => panic!("{}", msg),
21 false => serde::ser::Error::custom(msg),
22 }
23 }};
24}
25
26macro_rules! unsupported_types {
27 ($($method:ident: $ty:ty);* $(;)?) => {
28 $(
29 fn $method(self, _: $ty) -> Result<Self::Ok, Self::Error> {
30 Err(unsupported_type!(stringify!($ty)))
31 }
32 )*
33 };
34}
35
36impl<S> serde::Serializer for AssertNamed<S>
37where
38 S: serde::ser::SerializeMap,
39{
40 type Ok = S::Ok;
41 type Error = S::Error;
42 type SerializeSeq = Impossible<Self::Ok, Self::Error>;
43 type SerializeTuple = Impossible<Self::Ok, Self::Error>;
44 type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
45 type SerializeTupleVariant = SerializeTupleVariant<S>;
46 type SerializeMap = S;
47 type SerializeStruct = Self;
48 type SerializeStructVariant = SerializeStructVariant<S>;
49
50 unsupported_types! {
51 serialize_bool: bool;
52 serialize_i8: i8;
53 serialize_i16: i16;
54 serialize_i32: i32;
55 serialize_i64: i64;
56 serialize_i128: i128;
57 serialize_u8: u8;
58 serialize_u16: u16;
59 serialize_u32: u32;
60 serialize_u64: u64;
61 serialize_u128: u128;
62 serialize_f32: f32;
63 serialize_f64: f64;
64 serialize_char: char;
65 serialize_str: &str;
66 serialize_bytes: &[u8];
67 }
68
69 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
70 Err(unsupported_type!("unit"))
71 }
72 fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
73 self.serialize_unit()
74 }
75 fn serialize_unit_variant(
76 self,
77 _name: &'static str,
78 _variant_index: u32,
79 variant: &'static str,
80 ) -> Result<Self::Ok, Self::Error> {
81 self.serialize_str(variant)
82 }
83 fn serialize_newtype_struct<T>(
84 self,
85 _name: &'static str,
86 value: &T,
87 ) -> Result<Self::Ok, Self::Error>
88 where
89 T: ?Sized + Serialize,
90 {
91 value.serialize(self)
92 }
93 fn serialize_newtype_variant<T: ?Sized + Serialize>(
94 mut self,
95 _: &'static str,
96 _: u32,
97 variant: &'static str,
98 value: &T,
99 ) -> Result<Self::Ok, Self::Error> {
100 self.0.serialize_entry(variant, value)?;
102 self.0.end()
103 }
104 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
105 self.serialize_unit()
106 }
107 fn serialize_some<T: ?Sized + Serialize>(self, it: &T) -> Result<Self::Ok, Self::Error> {
108 it.serialize(self)
109 }
110 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
111 Err(unsupported_type!("sequence"))
112 }
113 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
114 self.serialize_seq(Some(len))
115 }
116 fn serialize_tuple_struct(
117 self,
118 _name: &'static str,
119 len: usize,
120 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
121 self.serialize_seq(Some(len))
122 }
123
124 fn serialize_tuple_variant(
125 self,
126 _name: &'static str,
127 _variant_index: u32,
128 variant: &'static str,
129 len: usize,
130 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
131 Ok(SerializeTupleVariant {
132 inner: self.0,
133 buffer: Vec::with_capacity(len),
134 name: variant,
135 })
136 }
137
138 fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
139 Ok(self.0)
140 }
141
142 fn serialize_struct(
143 self,
144 _name: &'static str,
145 _len: usize,
146 ) -> Result<Self::SerializeStruct, Self::Error> {
147 Ok(self)
148 }
149
150 fn serialize_struct_variant(
151 self,
152 _name: &'static str,
153 _variant_index: u32,
154 variant: &'static str,
155 _len: usize,
156 ) -> Result<Self::SerializeStructVariant, Self::Error> {
157 Ok(SerializeStructVariant {
158 inner: self.0,
159 buffer: BTreeMap::new(),
160 name: variant,
161 })
162 }
163}
164
165pub struct SerializeStructVariant<S> {
166 inner: S,
167 buffer: BTreeMap<&'static str, Value>,
168 name: &'static str,
169}
170impl<S> serde::ser::SerializeStructVariant for SerializeStructVariant<S>
171where
172 S: serde::ser::SerializeMap,
173{
174 type Ok = S::Ok;
175 type Error = S::Error;
176 fn serialize_field<T: ?Sized + Serialize>(
177 &mut self,
178 key: &'static str,
179 value: &T,
180 ) -> Result<(), Self::Error> {
181 self.buffer
182 .insert(key, serde_json::to_value(value).map_err(S::Error::custom)?);
183 Ok(())
184 }
185
186 fn end(mut self) -> Result<Self::Ok, Self::Error> {
187 self.inner.serialize_entry(self.name, &self.buffer)?;
188 self.inner.end()
189 }
190}
191
192pub struct SerializeTupleVariant<S> {
193 inner: S,
194 buffer: Vec<Value>,
195 name: &'static str,
196}
197
198impl<S> serde::ser::SerializeTupleVariant for SerializeTupleVariant<S>
199where
200 S: serde::ser::SerializeMap,
201{
202 type Ok = S::Ok;
203 type Error = S::Error;
204
205 fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
206 self.buffer
207 .push(serde_json::to_value(value).map_err(S::Error::custom)?);
208 Ok(())
209 }
210
211 fn end(mut self) -> Result<Self::Ok, Self::Error> {
212 self.inner.serialize_entry(self.name, &self.buffer)?;
213 self.inner.end()
214 }
215}
216
217impl<S> serde::ser::SerializeMap for AssertNamed<S>
218where
219 S: serde::ser::SerializeMap,
220{
221 type Ok = S::Ok;
222 type Error = S::Error;
223 fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<(), Self::Error> {
224 self.0.serialize_key(key)
225 }
226
227 fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
228 self.0.serialize_value(value)
229 }
230
231 fn end(self) -> Result<Self::Ok, Self::Error> {
232 self.0.end()
233 }
234}
235
236impl<S> serde::ser::SerializeStruct for AssertNamed<S>
237where
238 S: serde::ser::SerializeMap,
239{
240 type Ok = S::Ok;
241 type Error = S::Error;
242 fn serialize_field<T: ?Sized + Serialize>(
243 &mut self,
244 key: &'static str,
245 value: &T,
246 ) -> Result<(), Self::Error> {
247 self.0.serialize_entry(key, value)
248 }
249
250 fn end(self) -> Result<Self::Ok, Self::Error> {
251 self.0.end()
252 }
253}
254impl<S> serde::ser::SerializeStructVariant for AssertNamed<S>
255where
256 S: serde::ser::SerializeMap,
257{
258 type Ok = S::Ok;
259 type Error = S::Error;
260 fn serialize_field<T: ?Sized + Serialize>(
261 &mut self,
262 key: &'static str,
263 value: &T,
264 ) -> Result<(), Self::Error> {
265 self.0.serialize_entry(key, value)
266 }
267
268 fn end(self) -> Result<Self::Ok, Self::Error> {
269 self.0.end()
270 }
271}