@@ -57,6 +57,16 @@ use tracing_core::Metadata;
57
57
/// # drop(subscriber);
58
58
/// ```
59
59
///
60
+ /// `MakeWriter` is implemented for `Option<M>` when `M` implements `MakeWriter`.
61
+ ///
62
+ /// ```
63
+ /// # let enable_stdout = true;
64
+ /// let subscriber = tracing_subscriber::fmt()
65
+ /// .with_writer(enable_stdout.then_some(std::io::stdout))
66
+ /// .finish();
67
+ /// # drop(subscriber);
68
+ /// ```
69
+ ///
60
70
/// A closure can be used to introduce arbitrary logic into how the writer is
61
71
/// created. Consider the (admittedly rather silly) example of sending every 5th
62
72
/// event to stderr, and all other events to stdout:
@@ -1095,6 +1105,27 @@ where
1095
1105
}
1096
1106
}
1097
1107
1108
+ impl < ' a , M > MakeWriter < ' a > for Option < M >
1109
+ where
1110
+ M : MakeWriter < ' a > + ' static ,
1111
+ {
1112
+ type Writer = OptionalWriter < M :: Writer > ;
1113
+
1114
+ fn make_writer ( & ' a self ) -> Self :: Writer {
1115
+ match self {
1116
+ Some ( inner) => OptionalWriter :: some ( inner. make_writer ( ) ) ,
1117
+ None => OptionalWriter :: none ( ) ,
1118
+ }
1119
+ }
1120
+
1121
+ fn make_writer_for ( & ' a self , meta : & Metadata < ' _ > ) -> Self :: Writer {
1122
+ match self {
1123
+ Some ( inner) => OptionalWriter :: some ( inner. make_writer_for ( meta) ) ,
1124
+ None => OptionalWriter :: none ( ) ,
1125
+ }
1126
+ }
1127
+ }
1128
+
1098
1129
// === impl WriteAdaptor ===
1099
1130
1100
1131
#[ cfg( any( feature = "json" , feature = "time" ) ) ]
@@ -1391,4 +1422,80 @@ mod test {
1391
1422
has_lines ( & a_buf, & lines[ ..] ) ;
1392
1423
has_lines ( & b_buf, & lines[ ..] ) ;
1393
1424
}
1425
+
1426
+ #[ test]
1427
+ fn option_some_makewriter ( ) {
1428
+ let buf = Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ;
1429
+ let make_writer = Some ( MockMakeWriter :: new ( buf. clone ( ) ) ) ;
1430
+
1431
+ let lines = & [ ( Level :: INFO , "hello" ) , ( Level :: INFO , "world" ) ] ;
1432
+ let c = {
1433
+ #[ cfg( feature = "ansi" ) ]
1434
+ let f = Format :: default ( ) . without_time ( ) . with_ansi ( false ) ;
1435
+ #[ cfg( not( feature = "ansi" ) ) ]
1436
+ let f = Format :: default ( ) . without_time ( ) ;
1437
+ Collector :: builder ( )
1438
+ . event_format ( f)
1439
+ . with_writer ( make_writer)
1440
+ . with_max_level ( Level :: TRACE )
1441
+ . finish ( )
1442
+ } ;
1443
+ let _s = tracing:: collect:: set_default ( c) ;
1444
+ info ! ( "hello" ) ;
1445
+ info ! ( "world" ) ;
1446
+ has_lines ( & buf, & lines[ ..] ) ;
1447
+ }
1448
+
1449
+ #[ test]
1450
+ fn option_none_makewriter ( ) {
1451
+ let make_writer = Option :: < MockMakeWriter > :: None ;
1452
+
1453
+ let c = {
1454
+ #[ cfg( feature = "ansi" ) ]
1455
+ let f = Format :: default ( ) . without_time ( ) . with_ansi ( false ) ;
1456
+ #[ cfg( not( feature = "ansi" ) ) ]
1457
+ let f = Format :: default ( ) . without_time ( ) ;
1458
+ Collector :: builder ( )
1459
+ . event_format ( f)
1460
+ . with_writer ( make_writer)
1461
+ . with_max_level ( Level :: TRACE )
1462
+ . finish ( )
1463
+ } ;
1464
+ let _s = tracing:: collect:: set_default ( c) ;
1465
+ info ! ( "hello" ) ;
1466
+ info ! ( "world" ) ;
1467
+ }
1468
+
1469
+ #[ test]
1470
+ fn multi_tee ( ) {
1471
+ let always_buf = Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ;
1472
+ let some_buf = Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ;
1473
+
1474
+ let always_make_writer = MockMakeWriter :: new ( always_buf. clone ( ) ) ;
1475
+ let some_make_writer = Some ( MockMakeWriter :: new ( some_buf. clone ( ) ) ) ;
1476
+ let none_make_writer = Option :: < MockMakeWriter > :: None ;
1477
+
1478
+ let make_writer = always_make_writer
1479
+ . and ( some_make_writer)
1480
+ . and ( none_make_writer) ;
1481
+
1482
+ let lines = & [ ( Level :: INFO , "hello" ) , ( Level :: INFO , "world" ) ] ;
1483
+ let c = {
1484
+ #[ cfg( feature = "ansi" ) ]
1485
+ let f = Format :: default ( ) . without_time ( ) . with_ansi ( false ) ;
1486
+ #[ cfg( not( feature = "ansi" ) ) ]
1487
+ let f = Format :: default ( ) . without_time ( ) ;
1488
+ Collector :: builder ( )
1489
+ . event_format ( f)
1490
+ . with_writer ( make_writer)
1491
+ . with_max_level ( Level :: TRACE )
1492
+ . finish ( )
1493
+ } ;
1494
+ let _s = tracing:: collect:: set_default ( c) ;
1495
+ info ! ( "hello" ) ;
1496
+ info ! ( "world" ) ;
1497
+
1498
+ has_lines ( & always_buf, & lines[ ..] ) ;
1499
+ has_lines ( & some_buf, & lines[ ..] ) ;
1500
+ }
1394
1501
}
0 commit comments