@@ -266,6 +266,13 @@ pub trait Value: crate::sealed::Sealed {
266
266
#[ derive( Clone ) ]
267
267
pub struct DisplayValue < T : fmt:: Display > ( T ) ;
268
268
269
+ /// A `Value` which serializes using alternate `fmt::Display`.
270
+ ///
271
+ /// Uses `record_debug` in the `Value` implementation to
272
+ /// avoid an unnecessary evaluation.
273
+ #[ derive( Clone ) ]
274
+ pub struct DisplayAltValue < T : fmt:: Display > ( T ) ;
275
+
269
276
/// A `Value` which serializes as a string using `fmt::Debug`.
270
277
#[ derive( Clone ) ]
271
278
pub struct DebugValue < T : fmt:: Debug > ( T ) ;
@@ -279,6 +286,15 @@ where
279
286
DisplayValue ( t)
280
287
}
281
288
289
+ /// Wraps a type implementing `fmt::Display` as a `Value` that can be
290
+ /// recorded using its alternate `Display` implementation.
291
+ pub fn display_alt < T > ( t : T ) -> DisplayAltValue < T >
292
+ where
293
+ T : fmt:: Display ,
294
+ {
295
+ DisplayAltValue ( t)
296
+ }
297
+
282
298
/// Wraps a type implementing `fmt::Debug` as a `Value` that can be
283
299
/// recorded using its `Debug` implementation.
284
300
pub fn debug < T > ( t : T ) -> DebugValue < T >
@@ -639,6 +655,31 @@ impl<T: fmt::Display> fmt::Display for DisplayValue<T> {
639
655
}
640
656
}
641
657
658
+ // ===== impl DisplayAltValue =====
659
+
660
+ impl < T : fmt:: Display > crate :: sealed:: Sealed for DisplayAltValue < T > { }
661
+
662
+ impl < T > Value for DisplayAltValue < T >
663
+ where
664
+ T : fmt:: Display ,
665
+ {
666
+ fn record ( & self , key : & Field , visitor : & mut dyn Visit ) {
667
+ visitor. record_debug ( key, self )
668
+ }
669
+ }
670
+
671
+ impl < T : fmt:: Display > fmt:: Debug for DisplayAltValue < T > {
672
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
673
+ fmt:: Display :: fmt ( & format_args ! ( "{:#}" , self ) , f)
674
+ }
675
+ }
676
+
677
+ impl < T : fmt:: Display > fmt:: Display for DisplayAltValue < T > {
678
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
679
+ format_args ! ( "{:#}" , self . 0 ) . fmt ( f)
680
+ }
681
+ }
682
+
642
683
// ===== impl DebugValue =====
643
684
644
685
impl < T : fmt:: Debug > crate :: sealed:: Sealed for DebugValue < T > { }
@@ -1197,4 +1238,32 @@ mod test {
1197
1238
} ) ;
1198
1239
assert_eq ! ( result, format!( "{}" , r#"[61 62 63]" "[c0 ff ee]"# ) ) ;
1199
1240
}
1241
+
1242
+ #[ test]
1243
+ fn display_alt_value ( ) {
1244
+ struct AlternateString < ' a > ( & ' a str ) ;
1245
+
1246
+ impl std:: fmt:: Display for AlternateString < ' _ > {
1247
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
1248
+ if f. alternate ( ) {
1249
+ write ! ( f, "{} with alternate" , self . 0 )
1250
+ } else {
1251
+ self . 0 . fmt ( f)
1252
+ }
1253
+ }
1254
+ }
1255
+
1256
+ let alt_str = AlternateString ( "hello world" ) ;
1257
+
1258
+ let display = "hello world" ;
1259
+ assert_eq ! ( display, format!( "{}" , & alt_str) ) ;
1260
+
1261
+ let alt_display = "hello world with alternate" ;
1262
+ assert_eq ! ( alt_display, format!( "{:#}" , & alt_str) ) ;
1263
+
1264
+ assert_eq ! ( alt_display, format!( "{}" , display_alt( & alt_str) ) ) ;
1265
+ assert_eq ! ( alt_display, format!( "{:#}" , display_alt( & alt_str) ) ) ;
1266
+ assert_eq ! ( alt_display, format!( "{:?}" , display_alt( & alt_str) ) ) ;
1267
+ assert_eq ! ( alt_display, format!( "{:#?}" , display_alt( & alt_str) ) ) ;
1268
+ }
1200
1269
}
0 commit comments