1#![warn(
2 missing_debug_implementations,
3 missing_docs,
4 rust_2018_idioms,
5 unreachable_pub
6)]
7#![cfg_attr(not(feature = "std"), no_std)]
8
9use core::{fmt, mem};
45
46use serde::ser::{
47 Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
48 SerializeTupleStruct, SerializeTupleVariant,
49};
50use serde::{Serialize, Serializer};
51use valuable::{
52 EnumDef, Fields, NamedValues, StructDef, TupleDef, Valuable, Value, Variant, VariantDef, Visit,
53};
54
55pub struct Serializable<V>(V);
57
58impl<V> Serializable<V>
59where
60 V: Valuable,
61{
62 pub fn new(v: V) -> Self {
64 Self(v)
65 }
66
67 pub fn get_ref(&self) -> &V {
69 &self.0
70 }
71
72 pub fn get_mut(&mut self) -> &mut V {
74 &mut self.0
75 }
76
77 pub fn into_inner(self) -> V {
79 self.0
80 }
81}
82
83impl<V> fmt::Debug for Serializable<V>
84where
85 V: Valuable,
86{
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 fmt::Debug::fmt(&self.as_value(), f)
89 }
90}
91
92impl<V> Valuable for Serializable<V>
93where
94 V: Valuable,
95{
96 fn as_value(&self) -> Value<'_> {
97 self.0.as_value()
98 }
99
100 fn visit(&self, visit: &mut dyn Visit) {
101 self.0.visit(visit);
102 }
103}
104
105impl<V> Serialize for Serializable<V>
106where
107 V: Valuable,
108{
109 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
110 where
111 S: Serializer,
112 {
113 match self.0.as_value() {
114 Value::Bool(b) => serializer.serialize_bool(b),
115 Value::I8(n) => serializer.serialize_i8(n),
116 Value::I16(n) => serializer.serialize_i16(n),
117 Value::I32(n) => serializer.serialize_i32(n),
118 Value::I64(n) => serializer.serialize_i64(n),
119 Value::I128(n) => serializer.serialize_i128(n),
120 Value::Isize(n) => serializer.serialize_i64(n as _),
121 Value::U8(n) => serializer.serialize_u8(n),
122 Value::U16(n) => serializer.serialize_u16(n),
123 Value::U32(n) => serializer.serialize_u32(n),
124 Value::U64(n) => serializer.serialize_u64(n),
125 Value::U128(n) => serializer.serialize_u128(n),
126 Value::Usize(n) => serializer.serialize_u64(n as _),
127 Value::F32(n) => serializer.serialize_f32(n),
128 Value::F64(n) => serializer.serialize_f64(n),
129 Value::Char(c) => serializer.serialize_char(c),
130 Value::String(s) => serializer.serialize_str(s),
131 Value::Unit => serializer.serialize_unit(),
132 Value::Listable(l) => {
133 let size_hint = l.size_hint();
134 let mut ser = serializer.serialize_seq(Some(size_hint.1.unwrap_or(size_hint.0)))?;
135 let mut visitor = VisitList::<S>::Serializer(&mut ser);
136 l.visit(&mut visitor);
137 if let VisitList::Error(e) = visitor {
138 return Err(e);
139 }
140 ser.end()
141 }
142 Value::Mappable(m) => {
143 let size_hint = m.size_hint();
144 let mut ser = serializer.serialize_map(size_hint.1)?;
145 let mut visitor = VisitMap::<S>::Serializer(&mut ser);
146 m.visit(&mut visitor);
147 if let VisitMap::Error(e) = visitor {
148 return Err(e);
149 }
150 ser.end()
151 }
152 Value::Structable(s) => match s.definition() {
153 StructDef::Static { name, fields, .. } => {
154 let mut visitor = VisitStaticStruct::Start {
155 name,
156 fields,
157 serializer,
158 };
159 s.visit(&mut visitor);
160 match visitor {
161 VisitStaticStruct::End(res) => res,
162 _ => unreachable!(),
163 }
164 }
165 StructDef::Dynamic { fields, .. } => {
166 if fields.is_named() {
167 let mut ser = serializer.serialize_map(None)?;
169 let mut visitor = VisitDynamic::<S>::NamedFields(&mut ser);
170 s.visit(&mut visitor);
171 if let VisitDynamic::Error(e) = visitor {
172 return Err(e);
173 }
174 ser.end()
175 } else {
176 let mut ser = serializer.serialize_seq(None)?;
178 let mut visitor = VisitDynamic::<S>::UnnamedFields(&mut ser);
179 s.visit(&mut visitor);
180 if let VisitDynamic::Error(e) = visitor {
181 return Err(e);
182 }
183 ser.end()
184 }
185 }
186 def => unreachable!("{:?}", def),
187 },
188 Value::Enumerable(e) => match (e.definition(), e.variant()) {
189 (
190 EnumDef::Static {
191 name,
192 variants: def,
193 ..
194 },
195 Variant::Static(variant),
196 ) => {
197 let mut visitor = VisitStaticEnum::Start {
198 name,
199 def,
200 variant,
201 serializer,
202 };
203 e.visit(&mut visitor);
204 match visitor {
205 VisitStaticEnum::End(res) => res,
206 _ => unreachable!(),
207 }
208 }
209 (EnumDef::Dynamic { .. }, variant) => {
210 if variant.is_named_fields() {
211 let mut ser = serializer.serialize_map(None)?;
213 let mut visitor = VisitDynamic::<S>::NamedFields(&mut ser);
214 e.visit(&mut visitor);
215 if let VisitDynamic::Error(e) = visitor {
216 return Err(e);
217 }
218 ser.end()
219 } else {
220 let mut ser = serializer.serialize_seq(None)?;
222 let mut visitor = VisitDynamic::<S>::UnnamedFields(&mut ser);
223 e.visit(&mut visitor);
224 if let VisitDynamic::Error(e) = visitor {
225 return Err(e);
226 }
227 ser.end()
228 }
229 }
230 (EnumDef::Static { .. }, Variant::Dynamic(..)) => {
231 Err(S::Error::custom("dynamic variant in static enum"))
232 }
233 def => unreachable!("{:?}", def),
234 },
235 Value::Tuplable(t) => {
236 let def = t.definition();
237 if def.is_unit() {
238 return serializer.serialize_unit();
239 }
240 match def {
241 TupleDef::Static { fields: len, .. } => {
242 let ser = serializer.serialize_tuple(len)?;
243 let mut visitor = VisitStaticTuple::<S>::Start(ser);
244 t.visit(&mut visitor);
245 match visitor {
246 VisitStaticTuple::End(res) => res,
247 _ => unreachable!(),
248 }
249 }
250 TupleDef::Dynamic {
251 fields: size_hint, ..
252 } => {
253 let mut ser = serializer.serialize_seq(size_hint.1)?;
254 let mut visitor = VisitDynamic::<S>::UnnamedFields(&mut ser);
255 t.visit(&mut visitor);
256 if let VisitDynamic::Error(e) = visitor {
257 return Err(e);
258 }
259 ser.end()
260 }
261 def => unreachable!("{:?}", def),
262 }
263 }
264 #[cfg(feature = "std")]
265 Value::Path(p) => Serialize::serialize(p, serializer),
266 #[cfg(feature = "std")]
267 Value::Error(e) => SerializeError(e).serialize(serializer),
268
269 v => unimplemented!("{:?}", v),
270 }
271 }
272}
273
274enum VisitList<'a, S: Serializer> {
275 Serializer(&'a mut S::SerializeSeq),
276 Error(S::Error),
277}
278
279impl<S: Serializer> Visit for VisitList<'_, S> {
280 fn visit_value(&mut self, value: Value<'_>) {
281 if let Self::Serializer(ser) = self {
282 if let Err(e) = ser.serialize_element(&Serializable(value)) {
283 *self = Self::Error(e);
284 }
285 }
286 }
287
288 fn visit_entry(&mut self, _: Value<'_>, _: Value<'_>) {
289 if !matches!(self, Self::Error(..)) {
290 *self = Self::Error(S::Error::custom("visit_entry in list"));
291 }
292 }
293
294 fn visit_named_fields(&mut self, _: &NamedValues<'_>) {
295 if !matches!(self, Self::Error(..)) {
296 *self = Self::Error(S::Error::custom("visit_named_fields in list"));
297 }
298 }
299
300 fn visit_unnamed_fields(&mut self, _: &[Value<'_>]) {
301 if !matches!(self, Self::Error(..)) {
302 *self = Self::Error(S::Error::custom("visit_unnamed_fields in list"));
303 }
304 }
305}
306
307enum VisitMap<'a, S: Serializer> {
308 Serializer(&'a mut S::SerializeMap),
309 Error(S::Error),
310}
311
312impl<S: Serializer> Visit for VisitMap<'_, S> {
313 fn visit_entry(&mut self, key: Value<'_>, value: Value<'_>) {
314 if let Self::Serializer(ser) = self {
315 if let Err(e) = ser.serialize_entry(&Serializable(key), &Serializable(value)) {
316 *self = Self::Error(e);
317 }
318 }
319 }
320
321 fn visit_value(&mut self, _: Value<'_>) {
322 if !matches!(self, Self::Error(..)) {
323 *self = Self::Error(S::Error::custom("visit_value in map"));
324 }
325 }
326
327 fn visit_named_fields(&mut self, _: &NamedValues<'_>) {
328 if !matches!(self, Self::Error(..)) {
329 *self = Self::Error(S::Error::custom("visit_named_fields in map"));
330 }
331 }
332
333 fn visit_unnamed_fields(&mut self, _: &[Value<'_>]) {
334 if !matches!(self, Self::Error(..)) {
335 *self = Self::Error(S::Error::custom("visit_unnamed_fields in map"));
336 }
337 }
338}
339
340enum VisitStaticStruct<S: Serializer> {
341 Start {
342 name: &'static str,
343 fields: Fields<'static>,
344 serializer: S,
345 },
346 End(Result<S::Ok, S::Error>),
347 Tmp,
348}
349
350impl<S: Serializer> Visit for VisitStaticStruct<S> {
351 fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
352 let (name, fields, serializer) = match mem::replace(self, Self::Tmp) {
353 Self::Start {
354 name,
355 fields: Fields::Named(fields),
356 serializer,
357 } => (name, fields, serializer),
358 mut res @ Self::End(..) => {
359 if matches!(res, Self::End(Ok(..))) {
360 res = Self::End(Err(S::Error::custom(
361 "visit_named_fields called multiple times in static struct",
362 )));
363 }
364 *self = res;
365 return;
366 }
367 _ => unreachable!(),
368 };
369 let mut ser = match serializer.serialize_struct(name, named_values.len()) {
370 Ok(ser) => ser,
371 Err(e) => {
372 *self = Self::End(Err(e));
373 return;
374 }
375 };
376 for (i, (_, v)) in named_values.iter().enumerate() {
377 if let Err(e) = ser.serialize_field(fields[i].name(), &Serializable(v)) {
378 *self = Self::End(Err(e));
379 return;
380 }
381 }
382 *self = Self::End(ser.end());
383 }
384
385 fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
386 let (name, serializer) = match mem::replace(self, Self::Tmp) {
387 Self::Start {
388 name,
389 fields: Fields::Unnamed(_),
390 serializer,
391 } => (name, serializer),
392 mut res @ Self::End(..) => {
393 if matches!(res, Self::End(Ok(..))) {
394 res = Self::End(Err(S::Error::custom(
395 "visit_unnamed_fields called multiple times in static struct",
396 )));
397 }
398 *self = res;
399 return;
400 }
401 _ => unreachable!(),
402 };
403 if values.len() == 1 {
404 *self = Self::End(serializer.serialize_newtype_struct(name, &Serializable(values[0])));
405 return;
406 }
407 let mut ser = match serializer.serialize_tuple_struct(name, values.len()) {
408 Ok(ser) => ser,
409 Err(e) => {
410 *self = Self::End(Err(e));
411 return;
412 }
413 };
414 for v in values {
415 if let Err(e) = ser.serialize_field(&Serializable(v)) {
416 *self = Self::End(Err(e));
417 return;
418 }
419 }
420 *self = Self::End(ser.end());
421 }
422
423 fn visit_entry(&mut self, _: Value<'_>, _: Value<'_>) {
424 if !matches!(self, Self::End(Err(..))) {
425 *self = Self::End(Err(S::Error::custom("visit_entry in struct")));
426 }
427 }
428
429 fn visit_value(&mut self, _: Value<'_>) {
430 if !matches!(self, Self::End(Err(..))) {
431 *self = Self::End(Err(S::Error::custom("visit_value in struct")));
432 }
433 }
434}
435
436enum VisitStaticEnum<S: Serializer> {
437 Start {
438 name: &'static str,
439 def: &'static [VariantDef<'static>],
440 variant: &'static VariantDef<'static>,
441 serializer: S,
442 },
443 End(Result<S::Ok, S::Error>),
444 Tmp,
445}
446
447impl<S: Serializer> Visit for VisitStaticEnum<S> {
448 fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
449 let (name, def, variant, serializer) = match mem::replace(self, Self::Tmp) {
450 Self::Start {
451 name,
452 def,
453 variant,
454 serializer,
455 } => (name, def, variant, serializer),
456 mut res @ Self::End(..) => {
457 if matches!(res, Self::End(Ok(..))) {
458 res = Self::End(Err(S::Error::custom(
459 "visit_named_fields called multiple times in static enum",
460 )));
461 }
462 *self = res;
463 return;
464 }
465 _ => unreachable!(),
466 };
467 let variant_name = variant.name();
468 let variant_index = def.iter().position(|v| v.name() == variant_name).unwrap();
469 assert!(variant_index <= u32::MAX as usize);
470 let mut ser = match serializer.serialize_struct_variant(
471 name,
472 variant_index as _,
473 variant_name,
474 named_values.len(),
475 ) {
476 Ok(ser) => ser,
477 Err(e) => {
478 *self = Self::End(Err(e));
479 return;
480 }
481 };
482 let fields = match variant.fields() {
483 Fields::Named(fields) => fields,
484 Fields::Unnamed(_) => unreachable!(),
485 };
486 for (i, (_, v)) in named_values.iter().enumerate() {
487 if let Err(e) = ser.serialize_field(fields[i].name(), &Serializable(v)) {
488 *self = Self::End(Err(e));
489 return;
490 }
491 }
492 *self = Self::End(ser.end());
493 }
494
495 fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
496 let (name, def, variant, serializer) = match mem::replace(self, Self::Tmp) {
497 Self::Start {
498 name,
499 def,
500 variant,
501 serializer,
502 } => (name, def, variant, serializer),
503 mut res @ Self::End(..) => {
504 if matches!(res, Self::End(Ok(..))) {
505 res = Self::End(Err(S::Error::custom(
506 "visit_unnamed_fields called multiple times in static enum",
507 )));
508 }
509 *self = res;
510 return;
511 }
512 _ => unreachable!(),
513 };
514 let variant_name = variant.name();
515 let variant_index = def.iter().position(|v| v.name() == variant_name).unwrap();
516 assert!(variant_index <= u32::MAX as usize);
517 if values.len() == 1 {
518 *self = Self::End(serializer.serialize_newtype_variant(
519 name,
520 variant_index as _,
521 variant_name,
522 &Serializable(values[0]),
523 ));
524 return;
525 }
526 let mut ser = match serializer.serialize_tuple_variant(
527 name,
528 variant_index as _,
529 variant_name,
530 values.len(),
531 ) {
532 Ok(ser) => ser,
533 Err(e) => {
534 *self = Self::End(Err(e));
535 return;
536 }
537 };
538 for v in values {
539 if let Err(e) = ser.serialize_field(&Serializable(v)) {
540 *self = Self::End(Err(e));
541 return;
542 }
543 }
544 *self = Self::End(ser.end());
545 }
546
547 fn visit_entry(&mut self, _: Value<'_>, _: Value<'_>) {
548 if !matches!(self, Self::End(Err(..))) {
549 *self = Self::End(Err(S::Error::custom("visit_entry in enum")));
550 }
551 }
552
553 fn visit_value(&mut self, _: Value<'_>) {
554 if !matches!(self, Self::End(Err(..))) {
555 *self = Self::End(Err(S::Error::custom("visit_value in enum")));
556 }
557 }
558}
559
560enum VisitStaticTuple<S: Serializer> {
561 Start(S::SerializeTuple),
562 End(Result<S::Ok, S::Error>),
563 Tmp,
564}
565
566impl<S: Serializer> Visit for VisitStaticTuple<S> {
567 fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
568 let mut ser = match mem::replace(self, Self::Tmp) {
569 Self::Start(ser) => ser,
570 mut res @ Self::End(..) => {
571 if matches!(res, Self::End(Ok(..))) {
572 res = Self::End(Err(S::Error::custom(
573 "visit_unnamed_fields called multiple times in static tuple",
574 )));
575 }
576 *self = res;
577 return;
578 }
579 _ => unreachable!(),
580 };
581 for v in values {
582 if let Err(e) = ser.serialize_element(&Serializable(v)) {
583 *self = Self::End(Err(e));
584 return;
585 }
586 }
587 *self = Self::End(ser.end());
588 }
589
590 fn visit_named_fields(&mut self, _: &NamedValues<'_>) {
591 if !matches!(self, Self::End(Err(..))) {
592 *self = Self::End(Err(S::Error::custom("visit_named_fields in tuple")));
593 }
594 }
595
596 fn visit_entry(&mut self, _: Value<'_>, _: Value<'_>) {
597 if !matches!(self, Self::End(Err(..))) {
598 *self = Self::End(Err(S::Error::custom("visit_entry in tuple")));
599 }
600 }
601
602 fn visit_value(&mut self, _: Value<'_>) {
603 if !matches!(self, Self::End(Err(..))) {
604 *self = Self::End(Err(S::Error::custom("visit_value in tuple")));
605 }
606 }
607}
608
609enum VisitDynamic<'a, S: Serializer> {
611 NamedFields(&'a mut S::SerializeMap),
614 UnnamedFields(&'a mut S::SerializeSeq),
617 Error(S::Error),
618}
619
620impl<S: Serializer> Visit for VisitDynamic<'_, S> {
621 fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
622 let ser = match self {
623 Self::NamedFields(ser) => ser,
624 Self::Error(..) => return,
625 Self::UnnamedFields(..) => {
626 *self = Self::Error(S::Error::custom(
627 "visit_named_fields in unnamed dynamic struct/variant",
628 ));
629 return;
630 }
631 };
632 for (f, v) in named_values {
633 if let Err(e) = ser.serialize_entry(f.name(), &Serializable(v)) {
634 *self = Self::Error(e);
635 return;
636 }
637 }
638 }
639
640 fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
641 let ser = match self {
642 Self::UnnamedFields(ser) => ser,
643 Self::Error(..) => return,
644 Self::NamedFields(..) => {
645 *self = Self::Error(S::Error::custom(
646 "visit_unnamed_fields in named dynamic struct/variant",
647 ));
648 return;
649 }
650 };
651 for v in values {
652 if let Err(e) = ser.serialize_element(&Serializable(v)) {
653 *self = Self::Error(e);
654 return;
655 }
656 }
657 }
658
659 fn visit_entry(&mut self, _: Value<'_>, _: Value<'_>) {
660 if !matches!(self, Self::Error(..)) {
661 *self = Self::Error(S::Error::custom("visit_entry in dynamic struct/variant"));
662 }
663 }
664
665 fn visit_value(&mut self, _: Value<'_>) {
666 if !matches!(self, Self::Error(..)) {
667 *self = Self::Error(S::Error::custom("visit_value in dynamic struct/variant"));
668 }
669 }
670}
671
672#[cfg(feature = "std")]
673struct SerializeError<'a>(&'a dyn std::error::Error);
674
675#[cfg(feature = "std")]
676impl Serialize for SerializeError<'_> {
677 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
678 struct CollectStr<'a>(&'a dyn std::error::Error);
679 impl Serialize for CollectStr<'_> {
680 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
681 serializer.collect_str(&self.0)
682 }
683 }
684 let mut s = serializer.serialize_struct("Error", 2)?;
685 s.serialize_field("message", &CollectStr(self.0))?;
686 s.serialize_field("source", &self.0.source().map(SerializeError))?;
687 s.end()
688 }
689}