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