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, ScalarType};
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_u64(&mut self, value: u64) -> Result<(), Self::Error>;
33
34 fn serialize_u128(&mut self, value: u128) -> Result<(), Self::Error>;
36
37 fn serialize_i64(&mut self, value: i64) -> Result<(), Self::Error>;
39
40 fn serialize_i128(&mut self, value: i128) -> Result<(), Self::Error>;
42
43 fn serialize_f64(&mut self, value: f64) -> Result<(), Self::Error>;
45
46 fn serialize_bool(&mut self, value: bool) -> Result<(), Self::Error>;
48
49 fn serialize_char(&mut self, value: char) -> Result<(), Self::Error>;
51
52 fn serialize_str(&mut self, value: &str) -> Result<(), Self::Error>;
54
55 fn serialize_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error>;
57
58 fn serialize_none(&mut self) -> Result<(), Self::Error>;
62
63 fn serialize_unit(&mut self) -> Result<(), Self::Error>;
65
66 fn serialize_unit_variant(
75 &mut self,
76 variant_index: usize,
77 variant_name: &'static str,
78 ) -> Result<(), Self::Error>;
79
80 fn start_object(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
86
87 fn serialize_field_name(&mut self, name: &'static str) -> Result<(), Self::Error>;
93
94 fn start_array(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
100
101 fn start_map(&mut self, len: Option<usize>) -> Result<(), Self::Error>;
107
108 #[inline(always)]
110 fn serialize_u8(&mut self, value: u8) -> Result<(), Self::Error> {
111 self.serialize_u64(value as u64)
112 }
113
114 #[inline(always)]
116 fn serialize_u16(&mut self, value: u16) -> Result<(), Self::Error> {
117 self.serialize_u64(value as u64)
118 }
119
120 #[inline(always)]
122 fn serialize_u32(&mut self, value: u32) -> Result<(), Self::Error> {
123 self.serialize_u64(value as u64)
124 }
125
126 #[inline(always)]
128 fn serialize_usize(&mut self, value: usize) -> Result<(), Self::Error> {
129 self.serialize_u64(value as u64)
131 }
132
133 #[inline(always)]
135 fn serialize_i8(&mut self, value: i8) -> Result<(), Self::Error> {
136 self.serialize_i64(value as i64)
137 }
138
139 #[inline(always)]
141 fn serialize_i16(&mut self, value: i16) -> Result<(), Self::Error> {
142 self.serialize_i64(value as i64)
143 }
144
145 #[inline(always)]
147 fn serialize_i32(&mut self, value: i32) -> Result<(), Self::Error> {
148 self.serialize_i64(value as i64)
149 }
150
151 #[inline(always)]
153 fn serialize_isize(&mut self, value: isize) -> Result<(), Self::Error> {
154 self.serialize_i64(value as i64)
156 }
157
158 #[inline(always)]
160 fn serialize_f32(&mut self, value: f32) -> Result<(), Self::Error> {
161 self.serialize_f64(value as f64)
162 }
163
164 #[inline(always)]
166 fn begin_map_key(&mut self) -> Result<(), Self::Error> {
167 Ok(())
168 }
169
170 #[inline(always)]
172 fn end_map_key(&mut self) -> Result<(), Self::Error> {
173 Ok(())
174 }
175
176 #[inline(always)]
178 fn begin_map_value(&mut self) -> Result<(), Self::Error> {
179 Ok(())
180 }
181
182 #[inline(always)]
184 fn end_map_value(&mut self) -> Result<(), Self::Error> {
185 Ok(())
186 }
187
188 #[inline(always)]
190 fn end_object(&mut self) -> Result<(), Self::Error> {
191 Ok(())
192 }
193
194 #[inline(always)]
196 fn end_array(&mut self) -> Result<(), Self::Error> {
197 Ok(())
198 }
199
200 #[inline(always)]
202 fn end_map(&mut self) -> Result<(), Self::Error> {
203 Ok(())
204 }
205
206 #[inline(always)]
208 fn end_field(&mut self) -> Result<(), Self::Error> {
209 Ok(())
210 }
211}
212
213#[derive(Debug)]
217enum SerializeTask<'mem, 'facet> {
218 Value(Peek<'mem, 'facet>, Option<Field>),
219 EndObject,
221 EndArray,
222 EndMap,
223 EndMapKey,
224 EndMapValue,
225 EndField,
226 ObjectFields(PeekStruct<'mem, 'facet>),
228 ArrayItems(PeekList<'mem, 'facet>),
229 TupleStructFields(PeekStruct<'mem, 'facet>),
230 MapEntries(PeekMap<'mem, 'facet>),
231 SerializeFieldName(&'static str),
233 SerializeMapKey(Peek<'mem, 'facet>),
234 SerializeMapValue(Peek<'mem, 'facet>),
235}
236
237pub fn serialize_iterative<S>(peek: Peek<'_, '_>, serializer: &mut S) -> Result<(), S::Error>
241where
242 S: Serializer,
243{
244 let mut stack = Vec::new();
245 stack.push(SerializeTask::Value(peek, None));
246
247 while let Some(task) = stack.pop() {
248 match task {
249 SerializeTask::Value(mut cpeek, maybe_field) => {
250 debug!("Serializing a value");
251
252 if cpeek
253 .shape()
254 .attributes
255 .iter()
256 .any(|attr| *attr == ShapeAttribute::Transparent)
257 {
258 let old_shape = cpeek.shape();
259
260 let ps = cpeek.into_struct().unwrap();
262 cpeek = ps.field(0).unwrap();
263
264 let new_shape = cpeek.shape();
265 debug!(
266 "{old_shape} is transparent, let's serialize the inner {new_shape} instead"
267 );
268 }
269
270 match cpeek.shape().def {
271 Def::Scalar(_) => {
272 let cpeek = cpeek.innermost_peek();
273
274 match cpeek.scalar_type() {
276 Some(ScalarType::Unit) => serializer.serialize_unit()?,
277 Some(ScalarType::Bool) => {
278 serializer.serialize_bool(*cpeek.get::<bool>().unwrap())?
279 }
280 Some(ScalarType::Char) => {
281 serializer.serialize_char(*cpeek.get::<char>().unwrap())?
282 }
283
284 Some(ScalarType::Str) => {
286 serializer.serialize_str(cpeek.get::<&str>().unwrap())?
287 }
288 Some(ScalarType::String) => {
289 serializer.serialize_str(cpeek.get::<String>().unwrap())?
290 }
291 Some(ScalarType::CowStr) => serializer.serialize_str(
292 cpeek.get::<alloc::borrow::Cow<'_, str>>().unwrap().as_ref(),
293 )?,
294
295 Some(ScalarType::F32) => {
297 serializer.serialize_f32(*cpeek.get::<f32>().unwrap())?
298 }
299 Some(ScalarType::F64) => {
300 serializer.serialize_f64(*cpeek.get::<f64>().unwrap())?
301 }
302
303 Some(ScalarType::U8) => {
305 serializer.serialize_u8(*cpeek.get::<u8>().unwrap())?
306 }
307 Some(ScalarType::U16) => {
308 serializer.serialize_u16(*cpeek.get::<u16>().unwrap())?
309 }
310 Some(ScalarType::U32) => {
311 serializer.serialize_u32(*cpeek.get::<u32>().unwrap())?
312 }
313 Some(ScalarType::U64) => {
314 serializer.serialize_u64(*cpeek.get::<u64>().unwrap())?
315 }
316 Some(ScalarType::U128) => {
317 serializer.serialize_u128(*cpeek.get::<u128>().unwrap())?
318 }
319 Some(ScalarType::USize) => {
320 serializer.serialize_usize(*cpeek.get::<usize>().unwrap())?
321 }
322 Some(ScalarType::I8) => {
323 serializer.serialize_i8(*cpeek.get::<i8>().unwrap())?
324 }
325 Some(ScalarType::I16) => {
326 serializer.serialize_i16(*cpeek.get::<i16>().unwrap())?
327 }
328 Some(ScalarType::I32) => {
329 serializer.serialize_i32(*cpeek.get::<i32>().unwrap())?
330 }
331 Some(ScalarType::I64) => {
332 serializer.serialize_i64(*cpeek.get::<i64>().unwrap())?
333 }
334 Some(ScalarType::I128) => {
335 serializer.serialize_i128(*cpeek.get::<i128>().unwrap())?
336 }
337 Some(ScalarType::ISize) => {
338 serializer.serialize_isize(*cpeek.get::<isize>().unwrap())?
339 }
340 Some(unsupported) => panic!("Unsupported scalar type: {unsupported:?}"),
341 None => panic!("Unsupported shape: {}", cpeek.shape()),
342 }
343 }
344 Def::Struct(sd) => {
345 debug!("cpeek.shape(): {}", cpeek.shape());
346 match sd.kind {
347 StructKind::Unit => {
348 serializer.serialize_unit()?;
350 }
351 StructKind::Tuple | StructKind::TupleStruct => {
352 let peek_struct = cpeek.into_struct().unwrap();
353 let fields = peek_struct.fields_for_serialize().count();
354 serializer.start_array(Some(fields))?;
355 stack.push(SerializeTask::EndArray);
356 stack.push(SerializeTask::TupleStructFields(peek_struct));
357 }
358 StructKind::Struct => {
359 let peek_struct = cpeek.into_struct().unwrap();
360 let fields = peek_struct.fields_for_serialize().count();
361 serializer.start_object(Some(fields))?;
362 stack.push(SerializeTask::EndObject);
363 stack.push(SerializeTask::ObjectFields(peek_struct));
364 }
365 _ => {
366 unreachable!()
367 }
368 }
369 }
370 Def::Enum(_) => {
371 let peek_enum = cpeek.into_enum().unwrap();
372 let variant = peek_enum.active_variant();
373 let variant_index = peek_enum.variant_index();
374 let flattened = maybe_field.map(|f| f.flattened).unwrap_or_default();
375
376 if variant.data.fields.is_empty() {
377 serializer.serialize_unit_variant(variant_index, variant.name)?;
379 } else {
380 if !flattened {
381 serializer.start_object(Some(1))?;
383 stack.push(SerializeTask::EndObject);
384
385 serializer.serialize_field_name(variant.name)?;
387 }
388
389 if variant_is_newtype_like(variant) {
390 let fields = peek_enum.fields_for_serialize().collect::<Vec<_>>();
392 let (field, field_peek) = fields[0];
393 stack.push(SerializeTask::Value(field_peek, Some(field)));
395 } else if variant.data.kind == StructKind::Tuple
396 || variant.data.kind == StructKind::TupleStruct
397 {
398 let fields = peek_enum.fields_for_serialize().count();
400 serializer.start_array(Some(fields))?;
401 stack.push(SerializeTask::EndArray);
402
403 for (field, field_peek) in peek_enum.fields_for_serialize().rev() {
405 stack.push(SerializeTask::Value(field_peek, Some(field)));
406 }
407 } else {
408 let fields = peek_enum.fields_for_serialize().count();
410 serializer.start_object(Some(fields))?;
411 stack.push(SerializeTask::EndObject);
412
413 for (field, field_peek) in peek_enum.fields_for_serialize().rev() {
415 stack.push(SerializeTask::EndField);
416 stack.push(SerializeTask::Value(field_peek, Some(field)));
417 stack.push(SerializeTask::SerializeFieldName(field.name));
418 }
419 }
420 }
421 }
422 Def::List(_) | Def::Array(_) | Def::Slice(_) => {
423 let peek_list = cpeek.into_list().unwrap();
424 let len = peek_list.len();
425 serializer.start_array(Some(len))?;
426 stack.push(SerializeTask::EndArray);
427 stack.push(SerializeTask::ArrayItems(peek_list));
428 }
429 Def::Map(_) => {
430 let peek_map = cpeek.into_map().unwrap();
431 let len = peek_map.len();
432 serializer.start_map(Some(len))?;
433 stack.push(SerializeTask::EndMap);
434 stack.push(SerializeTask::MapEntries(peek_map));
435 }
436 Def::Option(_) => {
437 let opt = cpeek.into_option().unwrap();
438 if let Some(inner_peek) = opt.value() {
439 stack.push(SerializeTask::Value(inner_peek, None));
440 } else {
441 serializer.serialize_none()?;
442 }
443 }
444 Def::SmartPointer(_) => {
445 let _sp = cpeek.into_smart_pointer().unwrap();
446 panic!("TODO: Implement serialization for smart pointers");
447 }
448 Def::FunctionPointer(_) => {
449 serializer.serialize_unit()?;
451 }
452 _ => {
453 serializer.serialize_unit()?;
455 }
456 }
457 }
458
459 SerializeTask::ObjectFields(peek_struct) => {
461 for (field, field_peek) in peek_struct.fields_for_serialize().rev() {
463 stack.push(SerializeTask::EndField);
464 stack.push(SerializeTask::Value(field_peek, Some(field)));
465 stack.push(SerializeTask::SerializeFieldName(field.name));
466 }
467 }
468 SerializeTask::TupleStructFields(peek_struct) => {
469 for (field, field_peek) in peek_struct.fields_for_serialize().rev() {
471 stack.push(SerializeTask::Value(field_peek, Some(field)));
472 }
473 }
474 SerializeTask::ArrayItems(peek_list) => {
475 let items: Vec<_> = peek_list.iter().collect();
477 for item_peek in items.into_iter().rev() {
478 stack.push(SerializeTask::Value(item_peek, None));
479 }
480 }
481 SerializeTask::MapEntries(peek_map) => {
482 let entries = peek_map.iter().collect::<Vec<_>>();
484 for (key_peek, value_peek) in entries.into_iter().rev() {
485 stack.push(SerializeTask::SerializeMapValue(value_peek));
486 stack.push(SerializeTask::SerializeMapKey(key_peek));
487 }
488 }
489
490 SerializeTask::SerializeFieldName(name) => {
492 serializer.serialize_field_name(name)?;
493 }
494 SerializeTask::SerializeMapKey(key_peek) => {
495 stack.push(SerializeTask::EndMapKey);
496 stack.push(SerializeTask::Value(key_peek, None));
497 serializer.begin_map_key()?;
498 }
499 SerializeTask::SerializeMapValue(value_peek) => {
500 stack.push(SerializeTask::EndMapValue);
501 stack.push(SerializeTask::Value(value_peek, None));
502 serializer.begin_map_value()?;
503 }
504
505 SerializeTask::EndObject => {
507 serializer.end_object()?;
508 }
509 SerializeTask::EndArray => {
510 serializer.end_array()?;
511 }
512 SerializeTask::EndMap => {
513 serializer.end_map()?;
514 }
515 SerializeTask::EndMapKey => {
516 serializer.end_map_key()?;
517 }
518 SerializeTask::EndMapValue => {
519 serializer.end_map_value()?;
520 }
521 SerializeTask::EndField => {
522 serializer.end_field()?;
523 }
524 }
525 }
526
527 Ok(())
529}
530
531pub trait Serialize<'a>: Facet<'a> {
535 fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error>;
537}
538
539impl<'a, T> Serialize<'a> for T
540where
541 T: Facet<'a>,
542{
543 fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
545 let peek = Peek::new(self);
546 serialize_iterative(peek, serializer)
547 }
548}