format_tools/format/to_string_with_fallback.rs
1//!
2//! Flexible ToString augmentation.
3//!
4
5/// Define a private namespace for all its items.
6mod private
7{
8 use crate::*;
9
10 pub use super::
11 {
12 aref::{ Ref, Ref2, Ref3 },
13 };
14
15 use std::
16 {
17 borrow::Cow,
18 };
19
20 // ==
21
22 /// Trait to convert a type to a string with a fallback formatting.
23 pub trait ToStringWithFallback< 'a, How, Fallback1, Fallback2 >
24 where
25 How : 'static,
26 Fallback1 : 'static,
27 Fallback2 : 'static,
28 {
29 /// Converts the type to a string using the specified formatting or a fallback.
30 fn to_string_with_fallback( self ) -> Cow< 'a, str >
31 ;
32 }
33
34 impl< 'a, T, How, Fallback1, Fallback2 > ToStringWithFallback< 'a, How, Fallback1, Fallback2 >
35 for Ref< 'a, T, How, Fallback1, Fallback2 >
36 where
37 T : ToStringWith< How > + ?Sized,
38 How : 'static,
39 Fallback1 : 'static,
40 Fallback2 : 'static,
41 {
42 /// Converts the type to a string using the fallback formatting.
43 #[ inline ]
44 fn to_string_with_fallback( self ) -> Cow< 'a, str >
45 where
46 {
47 self.0.0.0.to_string_with()
48 }
49 }
50
51 impl< 'a, T, How, Fallback1, Fallback2 > ToStringWithFallback< 'a, How, Fallback1, Fallback2 >
52 for Ref2< 'a, T, How, Fallback1, Fallback2 >
53 where
54 T : ToStringWith< Fallback1 > + ?Sized,
55 How : 'static,
56 Fallback1 : 'static,
57 Fallback2 : 'static,
58 {
59 /// Converts the type to a string using the fallback formatting.
60 #[ inline ]
61 fn to_string_with_fallback( self ) -> Cow< 'a, str >
62 {
63 self.0.0.to_string_with()
64 }
65 }
66
67 impl< 'a, T, How, Fallback1, Fallback2 > ToStringWithFallback< 'a, How, Fallback1, Fallback2 >
68 for Ref3< 'a, T, How, Fallback1, Fallback2 >
69 where
70 T : ToStringWith< Fallback2 > + ?Sized,
71 How : 'static,
72 Fallback1 : 'static,
73 Fallback2 : 'static,
74 {
75 /// Converts the type to a string using the specified formatting.
76 #[ inline ]
77 fn to_string_with_fallback( self ) -> Cow< 'a, str >
78 {
79 self.0.to_string_with()
80 }
81 }
82
83 //
84
85 /// Macro to convert a value to a string using a specified formatting method with a fallback.
86 ///
87 /// # Parameters
88 /// - `$how`: The primary formatting type (e.g., `WithDebug`, `WithDisplay`).
89 /// - `$fallback1`: The first fallback formatting type.
90 /// - `$fallback2`: The second fallback formatting type (optional).
91 /// - `$src`: The source value to format.
92 ///
93 /// # Example
94 /// ```rust
95 /// use core::fmt;
96 /// use format_tools::
97 /// {
98 /// WithRef,
99 /// WithDebug,
100 /// WithDisplay,
101 /// to_string_with_fallback,
102 /// };
103 ///
104 /// // Define a struct that implements both Debug and Display traits.
105 /// struct Both;
106 ///
107 /// impl fmt::Debug for Both
108 /// {
109 /// fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result
110 /// {
111 /// write!( f, "This is debug" )
112 /// }
113 /// }
114 ///
115 /// impl fmt::Display for Both
116 /// {
117 /// fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result
118 /// {
119 /// write!( f, "This is display" )
120 /// }
121 /// }
122 ///
123 /// // Define a struct that implements only the Debug trait.
124 /// struct OnlyDebug;
125 ///
126 /// impl fmt::Debug for OnlyDebug
127 /// {
128 /// fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result
129 /// {
130 /// write!( f, "This is debug" )
131 /// }
132 /// }
133 ///
134 /// // Example usage: Using Both which implements both Debug and Display.
135 /// let src = Both;
136 /// let got = to_string_with_fallback!( WithDisplay, WithDebug, &src );
137 /// let exp = "This is display".to_string();
138 /// // The primary formatting method WithDisplay is used.
139 /// assert_eq!( got, exp );
140 ///
141 /// // Example usage: Using OnlyDebug which implements only Debug.
142 /// let src = OnlyDebug;
143 /// let got = to_string_with_fallback!( WithDisplay, WithDebug, &src );
144 /// let exp = "This is debug".to_string();
145 /// // The primary formatting method WithDisplay is not available, so the fallback WithDebug is used.
146 /// assert_eq!( got, exp );
147 ///
148 /// // Example usage: Using a struct that might need a second fallback.
149 /// struct OnlyDebugFallback;
150 ///
151 /// impl fmt::Debug for OnlyDebugFallback
152 /// {
153 /// fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result
154 /// {
155 /// write!( f, "This is debug fallback" )
156 /// }
157 /// }
158 ///
159 /// // Example usage: Using OnlyDebugFallback which implements only Debug.
160 /// let src = OnlyDebugFallback;
161 /// let got = to_string_with_fallback!( WithRef, WithDisplay, WithDebug, &src );
162 /// let exp = "This is debug fallback".to_string();
163 /// // The primary formatting method WithDisplay is not available, so the second fallback WithDebugFallback is used.
164 /// assert_eq!( got, exp );
165 /// ```
166
167 #[ macro_export ]
168 macro_rules! to_string_with_fallback
169 {
170
171 ( $how : ty, $fallback1 : ty, $src : expr )
172 =>
173 {{
174 use $crate::ToStringWithFallback;
175 $crate
176 ::to_string_with_fallback
177 ::Ref
178 ::< '_, _, $how, $fallback1, $fallback1 >
179 ::from( $src )
180 .to_string_with_fallback()
181 }};
182
183 ( $how : ty, $fallback1 : ty, $fallback2 : ty, $src : expr )
184 =>
185 {{
186 use $crate::ToStringWithFallback;
187 $crate
188 ::to_string_with_fallback
189 ::Ref
190 ::< '_, _, $how, $fallback1, $fallback2 >
191 ::from( $src )
192 .to_string_with_fallback()
193 }};
194
195 }
196
197 pub use to_string_with_fallback;
198}
199
200mod aref;
201
202#[ doc( inline ) ]
203#[ allow( unused_imports ) ]
204pub use own::*;
205
206/// Own namespace of the module.
207#[ allow( unused_imports ) ]
208pub mod own
209{
210 use super::*;
211
212 #[ doc( inline ) ]
213 pub use orphan::*;
214 #[ doc( inline ) ]
215 pub use private::
216 {
217 Ref,
218 Ref2,
219 Ref3,
220 to_string_with_fallback,
221 };
222}
223
224/// Orphan namespace of the module.
225#[ allow( unused_imports ) ]
226pub mod orphan
227{
228 use super::*;
229 pub use super::super::to_string_with_fallback;
230
231 #[ doc( inline ) ]
232 pub use exposed::*;
233
234 #[ doc( inline ) ]
235 pub use private::
236 {
237 ToStringWithFallback,
238 };
239
240}
241
242/// Exposed namespace of the module.
243#[ allow( unused_imports ) ]
244pub mod exposed
245{
246 use super::*;
247 #[ doc( inline ) ]
248 pub use prelude::*;
249
250 #[ doc( inline ) ]
251 pub use private::
252 {
253 };
254
255}
256
257/// Prelude to use essentials: `use my_module::prelude::*`.
258#[ allow( unused_imports ) ]
259pub mod prelude
260{
261 use super::*;
262}