1#![cfg_attr(not(feature = "std"), no_std)]
2#![warn(missing_docs)]
3#![warn(clippy::std_instead_of_core)]
4#![warn(clippy::std_instead_of_alloc)]
5#![deny(unsafe_code)]
6#![doc = include_str!("../README.md")]
7
8extern crate alloc;
9
10use alloc::string::String;
11use alloc::vec::Vec;
12
13use facet_core::{Def, Facet, Field, ShapeAttribute, StructKind};
14use facet_reflect::{HasFields, Peek, PeekList, PeekMap, PeekStruct};
15use log::debug;
16
17mod debug_serializer;
18
19fn variant_is_newtype_like(variant: &facet_core::Variant) -> bool {
20 variant.data.kind == facet_core::StructKind::Tuple && variant.data.fields.len() == 1
21}
22
23pub trait Serializer {
28 type Error;
30
31 fn serialize_u8(&mut self, value: u8) -> Result<(), Self::Error>;
33
34 fn serialize_u16(&mut self, value: u16) -> Result<(), Self::Error>;
36
37 fn serialize_u32(&mut self, value: u32) -> Result<(), Self::Error>;
39
40 fn serialize_u64(&mut self, value: u64) -> Result<(), Self::Error>;
42
43 fn serialize_u128(&mut self, value: u128) -> Result<(), Self::Error>;
45
46 fn serialize_usize(&mut self, value: usize) -> Result<(), Self::Error>;
48
49 fn serialize_i8(&mut self, value: i8) -> Result<(), Self::Error>;
51
52 fn serialize_i16(&mut self, value: i16) -> Result<(), Self::Error>;
54
55 fn serialize_i32(&mut self, value: i32) -> Result<(), Self::Error>;
57
58 fn serialize_i64(&mut self, value: i64) -> Result<(), Self::Error>;
60
61 fn serialize_i128(&mut self, value: i128) -> Result<(), Self::Error>;
63
64 fn serialize_isize(&mut self, value: isize) -> Result<(), Self::Error>;
66
67 fn serialize_f32(&mut self, value: f32) -> Result<(), Self::Error>;
69
70 fn serialize_f64(&mut self, value: f64) -> Result<(), Self::Error>;
72
73 fn serialize_bool(&mut self, value: bool) -> Result<(), Self::Error>;
75
76 fn serialize_char(&mut self, value: char) -> Result<(), Self::Error>;
78
79 fn serialize_str(&mut self, value: &str) -> Result<(), Self::Error>;
81
82 fn serialize_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error>;
84
85 fn serialize_none(&mut self) -> Result<(), Self::Error>;
89
90 fn serialize_unit(&mut self) -> Result<(), Self::Error>;
92
93 fn serialize_unit_variant(
102 &mut self,
103 variant_index: usize,
104 variant_name: &'static str,
105 ) -> Result<(), Self::Error>;
106
107 fn start_object(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
113
114 fn end_object(&mut self) -> Result<(), Self::Error>;
116
117 fn start_array(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
123
124 fn end_array(&mut self) -> Result<(), Self::Error>;
126
127 fn start_map(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
133
134 fn end_map(&mut self) -> Result<(), Self::Error>;
136
137 fn serialize_field_name(&mut self, name: &'static str) -> Result<(), Self::Error>;
145}
146
147#[derive(Debug)]
151enum SerializeTask<'mem, 'facet> {
152 Value(Peek<'mem, 'facet>, Option<Field>),
153 EndObject,
155 EndArray,
156 EndMap,
157 ObjectFields(PeekStruct<'mem, 'facet>),
159 ArrayItems(PeekList<'mem, 'facet>),
160 TupleStructFields(PeekStruct<'mem, 'facet>),
161 MapEntries(PeekMap<'mem, 'facet>),
162 SerializeFieldName(&'static str),
164 SerializeMapKey(Peek<'mem, 'facet>),
165 SerializeMapValue(Peek<'mem, 'facet>),
166}
167
168pub fn serialize_iterative<S>(peek: Peek<'_, '_>, serializer: &mut S) -> Result<(), S::Error>
172where
173 S: Serializer,
174{
175 let mut stack = Vec::new();
176 stack.push(SerializeTask::Value(peek, None));
177
178 while let Some(task) = stack.pop() {
179 match task {
180 SerializeTask::Value(mut cpeek, maybe_field) => {
181 debug!("Serializing a value");
182
183 if cpeek
184 .shape()
185 .attributes
186 .iter()
187 .any(|attr| matches!(attr, ShapeAttribute::Transparent))
188 {
189 let old_shape = cpeek.shape();
190
191 let ps = cpeek.into_struct().unwrap();
193 cpeek = ps.field(0).unwrap();
194
195 let new_shape = cpeek.shape();
196 debug!(
197 "{old_shape} is transparent, let's serialize the inner {new_shape} instead"
198 );
199 }
200
201 match cpeek.shape().def {
202 Def::Scalar(_) => {
203 let cpeek = cpeek.innermost_peek();
204
205 if cpeek.shape().is_type::<()>() {
207 serializer.serialize_unit()?
208 }
209 else if cpeek.shape().is_type::<bool>() {
211 let value = cpeek.get::<bool>().unwrap();
212 serializer.serialize_bool(*value)?
213 } else if cpeek.shape().is_type::<String>() {
214 let value = cpeek.get::<String>().unwrap();
215 serializer.serialize_str(value)?
216 } else if cpeek.shape().is_type::<alloc::borrow::Cow<'_, str>>() {
217 let value = cpeek.get::<alloc::borrow::Cow<'_, str>>().unwrap();
218 serializer.serialize_str(value.as_ref())?
219 } else if cpeek.shape().is_type::<&str>() {
220 let value = cpeek.get::<&str>().unwrap();
221 serializer.serialize_str(value)?
222 } else if cpeek.shape().is_type::<char>() {
223 let value = cpeek.get::<char>().unwrap();
224 serializer.serialize_char(*value)?
225 }
226 else if cpeek.shape().is_type::<u8>() {
228 let value = cpeek.get::<u8>().unwrap();
229 serializer.serialize_u8(*value)?
230 } else if cpeek.shape().is_type::<u16>() {
231 let value = cpeek.get::<u16>().unwrap();
232 serializer.serialize_u16(*value)?
233 } else if cpeek.shape().is_type::<u32>() {
234 let value = cpeek.get::<u32>().unwrap();
235 serializer.serialize_u32(*value)?
236 } else if cpeek.shape().is_type::<u64>() {
237 let value = cpeek.get::<u64>().unwrap();
238 serializer.serialize_u64(*value)?
239 } else if cpeek.shape().is_type::<u128>() {
240 let value = cpeek.get::<u128>().unwrap();
241 serializer.serialize_u128(*value)?
242 } else if cpeek.shape().is_type::<usize>() {
243 let value = cpeek.get::<usize>().unwrap();
244 serializer.serialize_usize(*value)?
245 } else if cpeek.shape().is_type::<i8>() {
246 let value = cpeek.get::<i8>().unwrap();
247 serializer.serialize_i8(*value)?
248 } else if cpeek.shape().is_type::<i16>() {
249 let value = cpeek.get::<i16>().unwrap();
250 serializer.serialize_i16(*value)?
251 } else if cpeek.shape().is_type::<i32>() {
252 let value = cpeek.get::<i32>().unwrap();
253 serializer.serialize_i32(*value)?
254 } else if cpeek.shape().is_type::<i64>() {
255 let value = cpeek.get::<i64>().unwrap();
256 serializer.serialize_i64(*value)?
257 } else if cpeek.shape().is_type::<i128>() {
258 let value = cpeek.get::<i128>().unwrap();
259 serializer.serialize_i128(*value)?
260 } else if cpeek.shape().is_type::<isize>() {
261 let value = cpeek.get::<isize>().unwrap();
262 serializer.serialize_isize(*value)?
263 }
264 else if cpeek.shape().is_type::<f32>() {
266 let value = cpeek.get::<f32>().unwrap();
267 serializer.serialize_f32(*value)?
268 } else if cpeek.shape().is_type::<f64>() {
269 let value = cpeek.get::<f64>().unwrap();
270 serializer.serialize_f64(*value)?
271 } else {
272 panic!("Unsupported shape: {}", cpeek.shape());
273 }
274 }
275 Def::Struct(sd) => {
276 debug!("cpeek.shape(): {}", cpeek.shape());
277 match sd.kind {
278 StructKind::Unit => {
279 serializer.serialize_unit()?;
281 }
282 StructKind::Tuple | StructKind::TupleStruct => {
283 let peek_struct = cpeek.into_struct().unwrap();
284 let fields = peek_struct.fields_for_serialize().count();
285 serializer.start_array(Some(fields))?;
286 stack.push(SerializeTask::EndArray);
287 stack.push(SerializeTask::TupleStructFields(peek_struct));
288 }
289 StructKind::Struct => {
290 let peek_struct = cpeek.into_struct().unwrap();
291 let fields = peek_struct.fields_for_serialize().count();
292 serializer.start_object(Some(fields))?;
293 stack.push(SerializeTask::EndObject);
294 stack.push(SerializeTask::ObjectFields(peek_struct));
295 }
296 _ => {
297 unreachable!()
298 }
299 }
300 }
301 Def::Enum(_) => {
302 let peek_enum = cpeek.into_enum().unwrap();
303 let variant = peek_enum.active_variant();
304 let variant_index = peek_enum.variant_index();
305 let flattened = maybe_field.map(|f| f.flattened).unwrap_or_default();
306
307 if variant.data.fields.is_empty() {
308 serializer.serialize_unit_variant(variant_index, variant.name)?;
310 } else {
311 if !flattened {
312 serializer.start_object(Some(1))?;
314 stack.push(SerializeTask::EndObject);
315
316 serializer.serialize_field_name(variant.name)?;
318 }
319
320 if variant_is_newtype_like(variant) {
321 let fields = peek_enum.fields_for_serialize().collect::<Vec<_>>();
323 let (field, field_peek) = fields[0];
324 stack.push(SerializeTask::Value(field_peek, Some(field)));
326 } else if variant.data.kind == StructKind::Tuple
327 || variant.data.kind == StructKind::TupleStruct
328 {
329 let fields = peek_enum.fields_for_serialize().count();
331 serializer.start_array(Some(fields))?;
332 stack.push(SerializeTask::EndArray);
333
334 for (field, field_peek) in peek_enum.fields_for_serialize().rev() {
336 stack.push(SerializeTask::Value(field_peek, Some(field)));
337 }
338 } else {
339 let fields = peek_enum.fields_for_serialize().count();
341 serializer.start_object(Some(fields))?;
342 stack.push(SerializeTask::EndObject);
343
344 for (field, field_peek) in peek_enum.fields_for_serialize().rev() {
346 stack.push(SerializeTask::Value(field_peek, Some(field)));
347 stack.push(SerializeTask::SerializeFieldName(field.name));
348 }
349 }
350 }
351 }
352 Def::List(_) | Def::Array(_) | Def::Slice(_) => {
353 let peek_list = cpeek.into_list().unwrap();
354 let len = peek_list.len();
355 serializer.start_array(Some(len))?;
356 stack.push(SerializeTask::EndArray);
357 stack.push(SerializeTask::ArrayItems(peek_list));
358 }
359 Def::Map(_) => {
360 let peek_map = cpeek.into_map().unwrap();
361 let len = peek_map.len();
362 serializer.start_map(Some(len))?;
363 stack.push(SerializeTask::EndMap);
364 stack.push(SerializeTask::MapEntries(peek_map));
365 }
366 Def::Option(_) => {
367 let opt = cpeek.into_option().unwrap();
368 if let Some(inner_peek) = opt.value() {
369 stack.push(SerializeTask::Value(inner_peek, None));
370 } else {
371 serializer.serialize_none()?;
372 }
373 }
374 Def::SmartPointer(_) => {
375 let _sp = cpeek.into_smart_pointer().unwrap();
376 panic!("TODO: Implement serialization for smart pointers");
377 }
378 Def::FunctionPointer(_) => {
379 serializer.serialize_unit()?;
381 }
382 _ => {
383 serializer.serialize_unit()?;
385 }
386 }
387 }
388
389 SerializeTask::ObjectFields(peek_struct) => {
391 for (field, field_peek) in peek_struct.fields_for_serialize().rev() {
393 stack.push(SerializeTask::Value(field_peek, Some(field)));
394 stack.push(SerializeTask::SerializeFieldName(field.name));
395 }
396 }
397 SerializeTask::TupleStructFields(peek_struct) => {
398 for (field, field_peek) in peek_struct.fields_for_serialize().rev() {
400 stack.push(SerializeTask::Value(field_peek, Some(field)));
401 }
402 }
403 SerializeTask::ArrayItems(peek_list) => {
404 let items: Vec<_> = peek_list.iter().collect();
406 for item_peek in items.into_iter().rev() {
407 stack.push(SerializeTask::Value(item_peek, None));
408 }
409 }
410 SerializeTask::MapEntries(peek_map) => {
411 let entries = peek_map.iter().collect::<Vec<_>>();
413 for (key_peek, value_peek) in entries.into_iter().rev() {
414 stack.push(SerializeTask::SerializeMapValue(value_peek));
415 stack.push(SerializeTask::SerializeMapKey(key_peek));
416 }
417 }
418
419 SerializeTask::SerializeFieldName(name) => {
421 serializer.serialize_field_name(name)?;
422 }
423 SerializeTask::SerializeMapKey(key_peek) => {
424 stack.push(SerializeTask::Value(key_peek, None));
425 }
426 SerializeTask::SerializeMapValue(value_peek) => {
427 stack.push(SerializeTask::Value(value_peek, None));
428 }
429
430 SerializeTask::EndObject => {
432 serializer.end_object()?;
433 }
434 SerializeTask::EndArray => {
435 serializer.end_array()?;
436 }
437 SerializeTask::EndMap => {
438 serializer.end_map()?;
439 }
440 }
441 }
442
443 Ok(())
445}
446
447pub trait Serialize<'a>: Facet<'a> {
451 fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error>;
453}
454
455impl<'a, T> Serialize<'a> for T
456where
457 T: Facet<'a>,
458{
459 fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
461 let peek = Peek::new(self);
462 serialize_iterative(peek, serializer)
463 }
464}