1#![doc(html_root_url = "https://docs.rs/serde_fmt/1.0.3")]
43#![cfg_attr(not(test), no_std)]
44
45#[cfg(all(not(test), not(feature = "std")))]
46extern crate core as std;
47
48#[cfg(any(test, feature = "std"))]
49extern crate std;
50
51use crate::std::fmt::{self, Debug, Display};
52
53use serde::ser::{
54 self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
55 SerializeTuple, SerializeTupleStruct, SerializeTupleVariant, Serializer,
56};
57
58pub fn to_writer(v: impl Serialize, mut w: impl fmt::Write) -> fmt::Result {
62 w.write_fmt(format_args!("{:?}", to_debug(v)))
63}
64
65pub fn to_debug<T>(v: T) -> ToDebug<T>
69where
70 T: Serialize,
71{
72 ToDebug(v)
73}
74
75#[derive(Clone, Copy)]
79pub struct ToDebug<T>(T);
80
81impl<T> Debug for ToDebug<T>
82where
83 T: Serialize,
84{
85 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
86 fmt::Display::fmt(self, f)
87 }
88}
89
90impl<T> Display for ToDebug<T>
95where
96 T: Serialize,
97{
98 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99 match self.0.serialize(Formatter::new(f)) {
103 Ok(()) => Ok(()),
104 Err(e) => write!(f, "<{}>", e),
105 }
106 }
107}
108
109impl<T> Serialize for ToDebug<T>
111where
112 T: Serialize,
113{
114 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
115 where
116 S: Serializer,
117 {
118 self.0.serialize(serializer)
119 }
120}
121
122struct Formatter<'a, 'b: 'a>(&'a mut fmt::Formatter<'b>);
123
124impl<'a, 'b: 'a> Formatter<'a, 'b> {
125 fn new(fmt: &'a mut fmt::Formatter<'b>) -> Self {
126 Formatter(fmt)
127 }
128
129 fn fmt(self, v: impl Debug) -> Result<(), Error> {
130 v.fmt(self.0).map_err(Into::into)
131 }
132}
133
134impl<'a, 'b: 'a> Serializer for Formatter<'a, 'b> {
135 type Ok = ();
136 type Error = Error;
137
138 type SerializeSeq = DebugSeq<'a, 'b>;
139 type SerializeTuple = DebugTuple<'a, 'b>;
140 type SerializeTupleStruct = DebugTupleStruct<'a, 'b>;
141 type SerializeTupleVariant = DebugTupleVariant<'a, 'b>;
142 type SerializeMap = DebugMap<'a, 'b>;
143 type SerializeStruct = DebugStruct<'a, 'b>;
144 type SerializeStructVariant = DebugStructVariant<'a, 'b>;
145
146 fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
147 self.fmt(v)
148 }
149
150 fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
151 self.fmt(v)
152 }
153
154 fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
155 self.fmt(v)
156 }
157
158 fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
159 self.fmt(v)
160 }
161
162 fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
163 self.fmt(v)
164 }
165
166 fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
167 self.fmt(v)
168 }
169
170 fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
171 self.fmt(v)
172 }
173
174 fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
175 self.fmt(v)
176 }
177
178 fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
179 self.fmt(v)
180 }
181
182 fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
183 self.fmt(v)
184 }
185
186 fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
187 self.fmt(v)
188 }
189
190 fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
191 self.fmt(v)
192 }
193
194 fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
195 self.fmt(v)
196 }
197
198 fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
199 self.fmt(v)
200 }
201
202 fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
203 self.fmt(v)
204 }
205
206 fn collect_str<T: ?Sized>(self, v: &T) -> Result<Self::Ok, Self::Error>
207 where
208 T: Display,
209 {
210 self.fmt(format_args!("{}", v))
211 }
212
213 fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
214 self.fmt(v)
215 }
216
217 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
218 write!(self.0, "None")?;
219 Ok(())
220 }
221
222 fn serialize_some<T>(self, v: &T) -> Result<Self::Ok, Self::Error>
223 where
224 T: ?Sized + Serialize,
225 {
226 self.serialize_newtype_struct("Some", v)
227 }
228
229 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
230 write!(self.0, "()")?;
231 Ok(())
232 }
233
234 fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
235 self.serialize_tuple_struct(name, 0)?.end()
236 }
237
238 fn serialize_unit_variant(
239 self,
240 _name: &'static str,
241 _variant_index: u32,
242 variant: &'static str,
243 ) -> Result<Self::Ok, Self::Error> {
244 self.serialize_tuple_struct(variant, 0)?.end()
245 }
246
247 fn serialize_newtype_struct<T>(self, name: &'static str, v: &T) -> Result<Self::Ok, Self::Error>
248 where
249 T: ?Sized + Serialize,
250 {
251 let mut tuple = self.serialize_tuple_struct(name, 1)?;
252 tuple.serialize_field(v)?;
253 tuple.end()
254 }
255
256 fn serialize_newtype_variant<T>(
257 self,
258 _name: &'static str,
259 _variant_index: u32,
260 variant: &'static str,
261 v: &T,
262 ) -> Result<Self::Ok, Self::Error>
263 where
264 T: ?Sized + Serialize,
265 {
266 let mut tuple = self.serialize_tuple_struct(variant, 1)?;
267 tuple.serialize_field(v)?;
268 tuple.end()
269 }
270
271 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
272 Ok(DebugSeq(self.0.debug_list()))
273 }
274
275 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
276 Ok(DebugTuple(self.0.debug_tuple("")))
277 }
278
279 fn serialize_tuple_struct(
280 self,
281 name: &'static str,
282 _len: usize,
283 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
284 Ok(DebugTupleStruct(self.0.debug_tuple(name)))
285 }
286
287 fn serialize_tuple_variant(
288 self,
289 _name: &'static str,
290 _variant_index: u32,
291 variant: &'static str,
292 _len: usize,
293 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
294 Ok(DebugTupleVariant(self.0.debug_tuple(variant)))
295 }
296
297 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
298 Ok(DebugMap(self.0.debug_map()))
299 }
300
301 fn serialize_struct(
302 self,
303 name: &'static str,
304 _len: usize,
305 ) -> Result<Self::SerializeStruct, Self::Error> {
306 Ok(DebugStruct(self.0.debug_struct(name)))
307 }
308
309 fn serialize_struct_variant(
310 self,
311 _name: &'static str,
312 _variant_index: u32,
313 variant: &'static str,
314 _len: usize,
315 ) -> Result<Self::SerializeStructVariant, Self::Error> {
316 Ok(DebugStructVariant(self.0.debug_struct(variant)))
317 }
318}
319
320struct DebugSeq<'a, 'b: 'a>(fmt::DebugList<'a, 'b>);
321
322impl<'a, 'b: 'a> SerializeSeq for DebugSeq<'a, 'b> {
323 type Ok = ();
324 type Error = Error;
325
326 fn serialize_element<T>(&mut self, v: &T) -> Result<Self::Ok, Self::Error>
327 where
328 T: ?Sized + Serialize,
329 {
330 self.0.entry(&to_debug(v));
331 Ok(())
332 }
333
334 fn end(mut self) -> Result<Self::Ok, Self::Error> {
335 self.0.finish().map_err(Into::into)
336 }
337}
338
339struct DebugTuple<'a, 'b: 'a>(fmt::DebugTuple<'a, 'b>);
340
341impl<'a, 'b: 'a> SerializeTuple for DebugTuple<'a, 'b> {
342 type Ok = ();
343 type Error = Error;
344
345 fn serialize_element<T>(&mut self, v: &T) -> Result<Self::Ok, Self::Error>
346 where
347 T: ?Sized + Serialize,
348 {
349 self.0.field(&to_debug(v));
350 Ok(())
351 }
352
353 fn end(mut self) -> Result<Self::Ok, Self::Error> {
354 self.0.finish().map_err(Into::into)
355 }
356}
357
358struct DebugTupleStruct<'a, 'b: 'a>(fmt::DebugTuple<'a, 'b>);
359
360impl<'a, 'b: 'a> SerializeTupleStruct for DebugTupleStruct<'a, 'b> {
361 type Ok = ();
362 type Error = Error;
363
364 fn serialize_field<T>(&mut self, v: &T) -> Result<Self::Ok, Self::Error>
365 where
366 T: ?Sized + Serialize,
367 {
368 self.0.field(&to_debug(v));
369 Ok(())
370 }
371
372 fn end(mut self) -> Result<Self::Ok, Self::Error> {
373 self.0.finish().map_err(Into::into)
374 }
375}
376
377struct DebugTupleVariant<'a, 'b: 'a>(fmt::DebugTuple<'a, 'b>);
378
379impl<'a, 'b: 'a> SerializeTupleVariant for DebugTupleVariant<'a, 'b> {
380 type Ok = ();
381 type Error = Error;
382
383 fn serialize_field<T>(&mut self, v: &T) -> Result<Self::Ok, Self::Error>
384 where
385 T: ?Sized + Serialize,
386 {
387 self.0.field(&to_debug(v));
388 Ok(())
389 }
390
391 fn end(mut self) -> Result<Self::Ok, Self::Error> {
392 self.0.finish().map_err(Into::into)
393 }
394}
395
396struct DebugStruct<'a, 'b: 'a>(fmt::DebugStruct<'a, 'b>);
397
398impl<'a, 'b: 'a> SerializeStruct for DebugStruct<'a, 'b> {
399 type Ok = ();
400 type Error = Error;
401
402 fn serialize_field<T>(&mut self, k: &'static str, v: &T) -> Result<Self::Ok, Self::Error>
403 where
404 T: ?Sized + Serialize,
405 {
406 self.0.field(k, &to_debug(v));
407 Ok(())
408 }
409
410 fn end(mut self) -> Result<Self::Ok, Self::Error> {
411 self.0.finish().map_err(Into::into)
412 }
413}
414
415struct DebugStructVariant<'a, 'b: 'a>(fmt::DebugStruct<'a, 'b>);
416
417impl<'a, 'b: 'a> SerializeStructVariant for DebugStructVariant<'a, 'b> {
418 type Ok = ();
419 type Error = Error;
420
421 fn serialize_field<T>(&mut self, k: &'static str, v: &T) -> Result<Self::Ok, Self::Error>
422 where
423 T: ?Sized + Serialize,
424 {
425 self.0.field(k, &to_debug(v));
426 Ok(())
427 }
428
429 fn end(mut self) -> Result<Self::Ok, Self::Error> {
430 self.0.finish().map_err(Into::into)
431 }
432}
433
434struct DebugMap<'a, 'b: 'a>(fmt::DebugMap<'a, 'b>);
435
436impl<'a, 'b: 'a> SerializeMap for DebugMap<'a, 'b> {
437 type Ok = ();
438 type Error = Error;
439
440 fn serialize_entry<K, V>(&mut self, k: &K, v: &V) -> Result<Self::Ok, Self::Error>
441 where
442 K: ?Sized + Serialize,
443 V: ?Sized + Serialize,
444 {
445 self.0.entry(&to_debug(k), &to_debug(v));
446 Ok(())
447 }
448
449 fn serialize_key<T>(&mut self, k: &T) -> Result<Self::Ok, Self::Error>
450 where
451 T: ?Sized + Serialize,
452 {
453 self.0.key(&to_debug(k));
454 Ok(())
455 }
456
457 fn serialize_value<T>(&mut self, v: &T) -> Result<Self::Ok, Self::Error>
458 where
459 T: ?Sized + Serialize,
460 {
461 self.0.value(&to_debug(v));
462 Ok(())
463 }
464
465 fn end(mut self) -> Result<Self::Ok, Self::Error> {
466 self.0.finish().map_err(Into::into)
467 }
468}
469
470#[derive(Debug)]
471struct Error;
472
473impl Display for Error {
474 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
475 write!(f, "failed to serialize to a standard formatter")
476 }
477}
478
479impl From<Error> for fmt::Error {
480 fn from(_: Error) -> fmt::Error {
481 fmt::Error
482 }
483}
484
485impl From<fmt::Error> for Error {
486 fn from(_: fmt::Error) -> Error {
487 Error
488 }
489}
490
491impl ser::StdError for Error {}
492
493impl ser::Error for Error {
494 fn custom<T>(_: T) -> Self
495 where
496 T: Display,
497 {
498 Error
499 }
500}
501
502#[cfg(test)]
503extern crate serde_derive;
504
505#[cfg(test)]
506mod tests {
507 use super::*;
508 use serde::ser::Error as _;
509 use serde_derive::*;
510
511 fn check_fmt(v: (impl fmt::Debug + Serialize)) {
512 assert_eq!(format!("{:?}", v), format!("{:?}", to_debug(v)));
513 }
514
515 #[test]
516 fn failing_serialize_does_not_panic_to_string() {
517 struct Kaboom;
518
519 impl Serialize for Kaboom {
520 fn serialize<S: Serializer>(&self, _: S) -> Result<S::Ok, S::Error> {
521 Err(S::Error::custom("kaboom!"))
522 }
523 }
524
525 #[derive(Serialize)]
526 struct NestedKaboom {
527 a: i32,
528 b: Kaboom,
529 c: i32,
530 }
531
532 assert_eq!("<failed to serialize to a standard formatter>", to_debug(Kaboom).to_string());
533 assert_eq!("NestedKaboom { a: 1, b: <failed to serialize to a standard formatter>, c: 2 }", to_debug(NestedKaboom { a: 1, b: Kaboom, c: 2 }).to_string());
534 }
535
536 #[test]
537 fn struct_fmt_is_consitent() {
538 #[derive(Serialize, Debug)]
539 struct Struct {
540 a: Signed,
541 b: Unsigned,
542 c: char,
543 d: &'static str,
544 e: &'static [u8],
545 f: (),
546 }
547
548 #[derive(Serialize, Debug)]
549 struct Signed {
550 a: i8,
551 b: i16,
552 c: i32,
553 d: i64,
554 }
555
556 #[derive(Serialize, Debug)]
557 struct Unsigned {
558 a: u8,
559 b: u16,
560 c: u32,
561 d: u64,
562 }
563
564 check_fmt(Struct {
565 a: Signed {
566 a: -1,
567 b: 42,
568 c: -42,
569 d: 42,
570 },
571 b: Unsigned {
572 a: 1,
573 b: 42,
574 c: 1,
575 d: 42,
576 },
577 c: 'a',
578 d: "a string",
579 e: &[1, 2, 3],
580 f: (),
581 });
582 }
583
584 #[test]
585 fn fmt_flags_are_consistent() {
586 use crate::std::format;
587
588 #[derive(Serialize, Debug)]
589 struct Struct {
590 a: i32,
591 b: i32,
592 }
593
594 assert_eq!(format!("{:03?}", 42), format!("{:03?}", to_debug(42)));
595 assert_eq!(format!("{:x?}", 42), format!("{:x?}", to_debug(42)));
596 assert_eq!(format!("{:X?}", 42), format!("{:X?}", to_debug(42)));
597 assert_eq!(
598 format!("{:#?}", Struct { a: 42, b: 17 }),
599 format!("{:#?}", to_debug(Struct { a: 42, b: 17 }))
600 );
601 }
602
603 #[test]
604 fn option_fmt_is_consistent() {
605 check_fmt(Option::Some::<i32>(42));
606 check_fmt(Option::None::<i32>);
607 }
608
609 #[test]
610 fn result_fmt_is_consistent() {
611 check_fmt(Result::Ok::<i32, i32>(42));
612 check_fmt(Result::Err::<i32, i32>(42));
613 }
614
615 #[test]
616 fn tuple_fmt_is_consistent() {
617 check_fmt((42, 17));
618 }
619
620 #[test]
621 fn tagged_fmt_is_consistent() {
622 #[derive(Serialize, Debug)]
623 enum Tagged {
624 Unit,
625 NewType(i32),
626 Tuple(i32, i32),
627 Struct { a: i32, b: i32 },
628 }
629
630 check_fmt(Tagged::Unit);
631 check_fmt(Tagged::NewType(42));
632 check_fmt(Tagged::Tuple(42, 17));
633 check_fmt(Tagged::Struct { a: 42, b: 17 });
634 }
635}