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