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 #[ macro_export ]
167 macro_rules! to_string_with_fallback
168 {
169
170 ( $how : ty, $fallback1 : ty, $src : expr )
171 =>
172 {{
173 use $crate::ToStringWithFallback;
174 $crate
175 ::to_string_with_fallback
176 ::Ref
177 ::< '_, _, $how, $fallback1, $fallback1 >
178 ::from( $src )
179 .to_string_with_fallback()
180 }};
181
182 ( $how : ty, $fallback1 : ty, $fallback2 : ty, $src : expr )
183 =>
184 {{
185 use $crate::ToStringWithFallback;
186 $crate
187 ::to_string_with_fallback
188 ::Ref
189 ::< '_, _, $how, $fallback1, $fallback2 >
190 ::from( $src )
191 .to_string_with_fallback()
192 }};
193
194 }
195
196 pub use to_string_with_fallback;
197}
198
199mod aref;
200
201#[ doc( inline ) ]
202#[ allow( unused_imports ) ]
203pub use own::*;
204
205/// Own namespace of the module.
206#[ allow( unused_imports ) ]
207pub mod own
208{
209 use super::*;
210
211 #[ doc( inline ) ]
212 pub use orphan::*;
213 #[ doc( inline ) ]
214 pub use private::
215 {
216 Ref,
217 Ref2,
218 Ref3,
219 to_string_with_fallback,
220 };
221}
222
223/// Orphan namespace of the module.
224#[ allow( unused_imports ) ]
225pub mod orphan
226{
227 use super::*;
228 pub use super::super::to_string_with_fallback;
229
230 #[ doc( inline ) ]
231 pub use exposed::*;
232
233 #[ doc( inline ) ]
234 pub use private::
235 {
236 ToStringWithFallback,
237 };
238
239}
240
241/// Exposed namespace of the module.
242#[ allow( unused_imports ) ]
243pub mod exposed
244{
245 use super::*;
246 #[ doc( inline ) ]
247 pub use prelude::*;
248
249 #[ doc( inline ) ]
250 pub use private::
251 {
252 };
253
254}
255
256/// Prelude to use essentials: `use my_module::prelude::*`.
257#[ allow( unused_imports ) ]
258pub mod prelude
259{
260 use super::*;
261}