xref: /linux/rust/kernel/fmt.rs (revision 808c999fc9e7c366fd47da564e69d579c1dc8279)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Formatting utilities.
4 //!
5 //! This module is intended to be used in place of `core::fmt` in kernel code.
6 
7 pub use core::fmt::{Arguments, Debug, Error, Formatter, Result, Write};
8 
9 /// Internal adapter used to route allow implementations of formatting traits for foreign types.
10 ///
11 /// It is inserted automatically by the [`fmt!`] macro and is not meant to be used directly.
12 ///
13 /// [`fmt!`]: crate::prelude::fmt!
14 #[doc(hidden)]
15 pub struct Adapter<T>(pub T);
16 
17 macro_rules! impl_fmt_adapter_forward {
18     ($($trait:ident),* $(,)?) => {
19         $(
20             impl<T: $trait> $trait for Adapter<T> {
21                 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
22                     let Self(t) = self;
23                     $trait::fmt(t, f)
24                 }
25             }
26         )*
27     };
28 }
29 
30 use core::fmt::{Binary, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex};
31 impl_fmt_adapter_forward!(Debug, LowerHex, UpperHex, Octal, Binary, Pointer, LowerExp, UpperExp);
32 
33 /// A copy of [`core::fmt::Display`] that allows us to implement it for foreign types.
34 ///
35 /// Types should implement this trait rather than [`core::fmt::Display`]. Together with the
36 /// [`Adapter`] type and [`fmt!`] macro, it allows for formatting foreign types (e.g. types from
37 /// core) which do not implement [`core::fmt::Display`] directly.
38 ///
39 /// [`fmt!`]: crate::prelude::fmt!
40 pub trait Display {
41     /// Same as [`core::fmt::Display::fmt`].
42     fn fmt(&self, f: &mut Formatter<'_>) -> Result;
43 }
44 
45 impl<T: ?Sized + Display> Display for &T {
46     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
47         Display::fmt(*self, f)
48     }
49 }
50 
51 impl<T: ?Sized + Display> core::fmt::Display for Adapter<&T> {
52     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
53         let Self(t) = self;
54         Display::fmt(t, f)
55     }
56 }
57 
58 macro_rules! impl_display_forward {
59     ($(
60         $( { $($generics:tt)* } )? $ty:ty $( { where $($where:tt)* } )?
61     ),* $(,)?) => {
62         $(
63             impl$($($generics)*)? Display for $ty $(where $($where)*)? {
64                 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
65                     core::fmt::Display::fmt(self, f)
66                 }
67             }
68         )*
69     };
70 }
71 
72 impl_display_forward!(
73     bool,
74     char,
75     core::panic::PanicInfo<'_>,
76     Arguments<'_>,
77     i128,
78     i16,
79     i32,
80     i64,
81     i8,
82     isize,
83     str,
84     u128,
85     u16,
86     u32,
87     u64,
88     u8,
89     usize,
90     {<T: ?Sized>} crate::sync::Arc<T> {where crate::sync::Arc<T>: core::fmt::Display},
91     {<T: ?Sized>} crate::sync::UniqueArc<T> {where crate::sync::UniqueArc<T>: core::fmt::Display},
92 );
93