1 /*! Format forwarding 2 3 This module provides wrapper types for each formatting trait other than `Debug` 4 which, when `Debug`-formatted, forward to the original trait instead of `Debug`. 5 6 Each wrapper type is a tuple struct so that it can be used as a named 7 constructor, such as in `.map(FmtDisplay)`. In addition, a blanket trait adds 8 extension methods `.fmt_<trait_name>>()` to provide the corresponding wrap. 9 10 Any modifiers in the format template string or struct modifier are passed 11 through to the desired trait implementation unchanged. The only effect of the 12 forwarding types in this module is to change the `?` template character to one 13 of the other trait signifiers. 14 !*/ 15 16 use core::{ 17 fmt::{ 18 self, 19 Binary, 20 Debug, 21 Display, 22 Formatter, 23 LowerExp, 24 LowerHex, 25 Octal, 26 Pointer, 27 UpperExp, 28 UpperHex, 29 }, 30 ops::{ 31 Deref, 32 DerefMut, 33 }, 34 }; 35 36 /// Wraps any value with a format-forward to `Debug`. 37 pub trait FmtForward: Sized { 38 /// Causes `self` to use its `Binary` implementation when `Debug`-formatted. fmt_binary(self) -> FmtBinary<Self> where Self: Binary39 fn fmt_binary(self) -> FmtBinary<Self> 40 where Self: Binary { 41 FmtBinary(self) 42 } 43 44 /// Causes `self` to use its `Display` implementation when 45 /// `Debug`-formatted. fmt_display(self) -> FmtDisplay<Self> where Self: Display46 fn fmt_display(self) -> FmtDisplay<Self> 47 where Self: Display { 48 FmtDisplay(self) 49 } 50 51 /// Causes `self` to use its `LowerExp` implementation when 52 /// `Debug`-formatted. fmt_lower_exp(self) -> FmtLowerExp<Self> where Self: LowerExp53 fn fmt_lower_exp(self) -> FmtLowerExp<Self> 54 where Self: LowerExp { 55 FmtLowerExp(self) 56 } 57 58 /// Causes `self` to use its `LowerHex` implementation when 59 /// `Debug`-formatted. fmt_lower_hex(self) -> FmtLowerHex<Self> where Self: LowerHex60 fn fmt_lower_hex(self) -> FmtLowerHex<Self> 61 where Self: LowerHex { 62 FmtLowerHex(self) 63 } 64 65 /// Causes `self` to use its `Octal` implementation when `Debug`-formatted. fmt_octal(self) -> FmtOctal<Self> where Self: Octal66 fn fmt_octal(self) -> FmtOctal<Self> 67 where Self: Octal { 68 FmtOctal(self) 69 } 70 71 /// Causes `self` to use its `Pointer` implementation when 72 /// `Debug`-formatted. fmt_pointer(self) -> FmtPointer<Self> where Self: Pointer73 fn fmt_pointer(self) -> FmtPointer<Self> 74 where Self: Pointer { 75 FmtPointer(self) 76 } 77 78 /// Causes `self` to use its `UpperExp` implementation when 79 /// `Debug`-formatted. fmt_upper_exp(self) -> FmtUpperExp<Self> where Self: UpperExp80 fn fmt_upper_exp(self) -> FmtUpperExp<Self> 81 where Self: UpperExp { 82 FmtUpperExp(self) 83 } 84 85 /// Causes `self` to use its `UpperHex` implementation when 86 /// `Debug`-formatted. fmt_upper_hex(self) -> FmtUpperHex<Self> where Self: UpperHex87 fn fmt_upper_hex(self) -> FmtUpperHex<Self> 88 where Self: UpperHex { 89 FmtUpperHex(self) 90 } 91 } 92 93 impl<T: Sized> FmtForward for T { 94 } 95 96 /// Forwards a type’s `Binary` formatting implementation to `Debug`. 97 #[repr(transparent)] 98 pub struct FmtBinary<T: Binary>(pub T); 99 100 /// Forwards a type’s `Display` formatting implementation to `Debug`. 101 #[repr(transparent)] 102 pub struct FmtDisplay<T: Display>(pub T); 103 104 /// Forwards a type’s `LowerExp` formatting implementation to `Debug`. 105 #[repr(transparent)] 106 pub struct FmtLowerExp<T: LowerExp>(pub T); 107 108 /// Forwards a type’s `LowerHex` formatting implementation to `Debug`. 109 #[repr(transparent)] 110 pub struct FmtLowerHex<T: LowerHex>(pub T); 111 112 /// Forwards a type’s `Octal` formatting implementation to `Debug`. 113 #[repr(transparent)] 114 pub struct FmtOctal<T: Octal>(pub T); 115 116 /// Forwards a type’s `Pointer` formatting implementation to `Debug`. 117 #[repr(transparent)] 118 pub struct FmtPointer<T: Pointer>(pub T); 119 120 /// Forwards a type’s `UpperExp` formatting implementation to `Debug`. 121 #[repr(transparent)] 122 pub struct FmtUpperExp<T: UpperExp>(pub T); 123 124 /// Forwards a type’s `UpperHex` formatting implementation to `Debug`. 125 #[repr(transparent)] 126 pub struct FmtUpperHex<T: UpperHex>(pub T); 127 128 macro_rules! fmt { 129 ($($w:ty => $t:ident),* $(,)?) => { $( 130 impl<T: $t + Binary> Binary for $w { 131 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 132 Binary::fmt(&self.0, fmt) 133 } 134 } 135 136 impl<T: $t> Debug for $w { 137 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 138 <T as $t>::fmt(&self.0, fmt) 139 } 140 } 141 142 impl<T: $t + Display> Display for $w { 143 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 144 Display::fmt(&self.0, fmt) 145 } 146 } 147 148 impl<T: $t + LowerExp> LowerExp for $w { 149 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 150 LowerExp::fmt(&self.0, fmt) 151 } 152 } 153 154 impl<T: $t + LowerHex> LowerHex for $w { 155 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 156 LowerHex::fmt(&self.0, fmt) 157 } 158 } 159 160 impl<T: $t + Octal> Octal for $w { 161 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 162 Octal::fmt(&self.0, fmt) 163 } 164 } 165 166 impl<T: $t + Pointer> Pointer for $w { 167 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 168 Pointer::fmt(&self.0, fmt) 169 } 170 } 171 172 impl<T: $t + UpperExp> UpperExp for $w { 173 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 174 UpperExp::fmt(&self.0, fmt) 175 } 176 } 177 178 impl<T: $t + UpperHex> UpperHex for $w { 179 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 180 UpperHex::fmt(&self.0, fmt) 181 } 182 } 183 184 impl<T: $t> Deref for $w { 185 type Target = T; 186 187 fn deref(&self) -> &Self::Target { 188 &self.0 189 } 190 } 191 192 impl<T: $t> DerefMut for $w { 193 fn deref_mut(&mut self) -> &mut Self::Target { 194 &mut self.0 195 } 196 } 197 198 impl<T: $t> AsRef<T> for $w { 199 fn as_ref(&self) -> &T { 200 &self.0 201 } 202 } 203 204 impl<T: $t> AsMut<T> for $w { 205 fn as_mut(&mut self) -> &mut T { 206 &mut self.0 207 } 208 } 209 )* }; 210 } 211 212 fmt!( 213 FmtBinary<T> => Binary, 214 FmtDisplay<T> => Display, 215 FmtLowerExp<T> => LowerExp, 216 FmtLowerHex<T> => LowerHex, 217 FmtOctal<T> => Octal, 218 FmtPointer<T> => Pointer, 219 FmtUpperExp<T> => UpperExp, 220 FmtUpperHex<T> => UpperHex, 221 ); 222