1use core::fmt::{self, Debug, Display, Formatter};
2
3pub struct FmtFn<F>
5where
6 F: ?Sized,
7{
8 values_fn: F,
9}
10
11impl<F> FmtFn<F> {
12 const fn new(values_fn: F) -> Self {
13 Self { values_fn }
14 }
15}
16
17impl<F> Display for FmtFn<F>
18where
19 F: Fn(&mut Formatter) -> fmt::Result + ?Sized,
20{
21 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
22 (self.values_fn)(f)
23 }
24}
25
26impl<F> Debug for FmtFn<F>
27where
28 F: Fn(&mut Formatter) -> fmt::Result + ?Sized,
29{
30 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
31 (self.values_fn)(f)
32 }
33}
34
35pub const fn fmt_fn<F>(f: F) -> FmtFn<F>
46where
47 F: Fn(&mut Formatter) -> fmt::Result,
48{
49 FmtFn::new(f)
50}
51
52#[cfg(test)]
53mod tests {
54 use super::FmtFn;
55 use core::fmt::{self, Formatter};
56
57 #[test]
58 fn test_fmt_fn() {
59 let fmt = super::fmt_fn(|f| f.write_str("foo"));
60
61 assert_eq!(std::format!("{fmt:?}"), "foo");
62 assert_eq!(std::format!("{fmt}"), "foo");
63 }
64
65 #[test]
66 fn test_coerce_unsized() {
67 let fmt: &FmtFn<dyn Fn(&mut Formatter) -> fmt::Result> = &super::fmt_fn(|f| f.write_str("foo"));
68
69 assert_eq!(std::format!("{fmt:?}"), "foo");
70 assert_eq!(std::format!("{fmt}"), "foo");
71 }
72}