debug_fn/
lib.rs

1//! This crate provides an adapter that allows you to turn any closure
2//! `Fn(&mut Formatter<'_>) -> fmt::Result` into a type that implements `Display` and
3//! `Debug`.
4//!
5//! # Example
6//!
7//! ```
8//! use core::fmt;
9//! use core::fmt::Formatter;
10//! use debug_fn::debug_fn;
11//!
12//! fn hello(f: &mut Formatter<'_>, user_id: Option<u64>) -> fmt::Result {
13//!     if let Some(user_id) = user_id {
14//!         write!(f, "user number {}", user_id)
15//!     } else {
16//!         write!(f, "anonymous user")
17//!     }
18//! }
19//!
20//! assert_eq!(format!("Hello {}", debug_fn(|f| hello(f, Some(1234)))), "Hello user number 1234");
21//! assert_eq!(format!("Hello {}", debug_fn(|f| hello(f, None))), "Hello anonymous user");
22//! ```
23
24#![no_std]
25
26use core::{
27    fmt,
28    fmt::{Debug, Display, Formatter},
29};
30
31/// A type that implements `Display` and `Debug`.
32pub struct DebugFn<F>(F)
33where
34    F: Fn(&mut Formatter<'_>) -> fmt::Result;
35
36/// Creates a type that implements `Display` and `Debug` from a closure.
37///
38/// # Example
39///
40/// ```
41/// use core::fmt::Display;
42/// use debug_fn::debug_fn;
43///
44/// fn format_string(s: &str) -> impl Display + use<'_> {
45///     debug_fn(move |f| f.write_str(s))
46/// }
47/// ```
48#[inline(always)]
49pub fn debug_fn<F>(f: F) -> DebugFn<F>
50where
51    F: Fn(&mut Formatter<'_>) -> fmt::Result,
52{
53    DebugFn(f)
54}
55
56impl<F> Debug for DebugFn<F>
57where
58    F: Fn(&mut Formatter<'_>) -> fmt::Result,
59{
60    #[inline]
61    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
62        self.0(f)
63    }
64}
65
66impl<F> Display for DebugFn<F>
67where
68    F: Fn(&mut Formatter<'_>) -> fmt::Result,
69{
70    #[inline]
71    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
72        self.0(f)
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    extern crate alloc;
79
80    use {crate::debug_fn, alloc::format};
81
82    #[test]
83    fn test() {
84        let res = format!("{}", debug_fn(|f| f.write_str("test")));
85        assert_eq!(res, "test");
86
87        let res = format!("{:?}", debug_fn(|f| f.write_str("test")));
88        assert_eq!(res, "test");
89    }
90}