sval_fmt/
to_fmt.rs

1use core::fmt;
2
3use crate::writer::Writer;
4
5/**
6Adapt an [`sval::Value`] into a [`fmt::Debug`] or [`fmt::Display`].
7*/
8#[repr(transparent)]
9pub struct ToFmt<V: ?Sized>(V);
10
11impl<V: sval::Value> ToFmt<V> {
12    /**
13    Adapt an [`sval::Value`] into a [`fmt::Debug`] or [`fmt::Display`].
14    */
15    pub fn new(value: V) -> ToFmt<V> {
16        ToFmt(value)
17    }
18}
19
20impl<V: sval::Value + ?Sized> ToFmt<V> {
21    /**
22    Adapt a reference to an [`sval::Value`] into a [`fmt::Debug`] or [`fmt::Display`].
23    */
24    pub fn new_borrowed<'a>(value: &'a V) -> &'a ToFmt<V> {
25        // SAFETY: `&'a V` and `&'a ToDebug<V>` have the same ABI
26        unsafe { &*(value as *const _ as *const ToFmt<V>) }
27    }
28}
29
30/**
31Format a value into an underlying formatter.
32*/
33pub fn stream_to_fmt(fmt: &mut fmt::Formatter, v: impl sval::Value) -> fmt::Result {
34    v.stream(&mut Writer::new(fmt)).map_err(|_| fmt::Error)
35}
36
37impl<V: sval::Value> fmt::Debug for ToFmt<V> {
38    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39        fmt::Display::fmt(self, f)
40    }
41}
42
43impl<V: sval::Value> fmt::Display for ToFmt<V> {
44    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
45        // If the `Value` impl fails then swallow the error rather than
46        // propagate it; Traits like `ToString` expect formatting to be
47        // infallible unless the writer itself fails
48        match stream_to_fmt(f, &self.0) {
49            Ok(()) => Ok(()),
50            Err(e) => write!(f, "<{}>", e),
51        }
52    }
53}