Skip to main content

kernel/
fmt.rs

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
7pub 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)]
22pub struct Adapter<T>(pub T);
23
24macro_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
37use core::fmt::{
38    Binary,
39    LowerExp,
40    LowerHex,
41    Octal,
42    Pointer,
43    UpperExp,
44    UpperHex, //
45};
46impl_fmt_adapter_forward!(Debug, LowerHex, UpperHex, Octal, Binary, LowerExp, UpperExp);
47
48impl<T: ?Sized + Pointer> Pointer for Adapter<&T> {
49    #[inline]
50    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
51        Pointer::fmt(self.0, f)
52    }
53}
54
55/// A copy of [`core::fmt::Display`] that allows us to implement it for foreign types.
56///
57/// Types should implement this trait rather than [`core::fmt::Display`]. Together with the
58/// [`Adapter`] type and [`fmt!`] macro, it allows for formatting foreign types (e.g. types from
59/// core) which do not implement [`core::fmt::Display`] directly.
60///
61/// [`fmt!`]: crate::prelude::fmt!
62pub trait Display {
63    /// Same as [`core::fmt::Display::fmt`].
64    fn fmt(&self, f: &mut Formatter<'_>) -> Result;
65}
66
67impl<T: ?Sized + Display> Display for &T {
68    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
69        Display::fmt(*self, f)
70    }
71}
72
73impl<T: ?Sized + Display> core::fmt::Display for Adapter<&T> {
74    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
75        let Self(t) = self;
76        Display::fmt(t, f)
77    }
78}
79
80macro_rules! impl_display_forward {
81    ($(
82        $( { $($generics:tt)* } )? $ty:ty $( { where $($where:tt)* } )?
83    ),* $(,)?) => {
84        $(
85            impl$($($generics)*)? Display for $ty $(where $($where)*)? {
86                fn fmt(&self, f: &mut Formatter<'_>) -> Result {
87                    core::fmt::Display::fmt(self, f)
88                }
89            }
90        )*
91    };
92}
93
94impl_display_forward!(
95    bool,
96    char,
97    core::panic::PanicInfo<'_>,
98    Arguments<'_>,
99    i128,
100    i16,
101    i32,
102    i64,
103    i8,
104    isize,
105    str,
106    u128,
107    u16,
108    u32,
109    u64,
110    u8,
111    usize,
112    {<T: ?Sized>} crate::sync::Arc<T> {where crate::sync::Arc<T>: core::fmt::Display},
113    {<T: ?Sized>} crate::sync::UniqueArc<T> {where crate::sync::UniqueArc<T>: core::fmt::Display},
114);