@@ -398,23 +398,70 @@ pub enum UserDisplayStyle {
398
398
DisplayName ,
399
399
}
400
400
401
- #[ derive( Clone , Copy , Debug , Deserialize , Eq , PartialEq ) ]
402
- #[ serde( rename_all = "lowercase" ) ]
403
- pub enum NotifyVia {
401
+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
402
+ pub struct NotifyVia {
404
403
/// Deliver notifications via terminal bell.
405
- Bell ,
404
+ pub bell : bool ,
406
405
/// Deliver notifications via desktop mechanism.
407
406
#[ cfg( feature = "desktop" ) ]
408
- Desktop ,
407
+ pub desktop : bool ,
409
408
}
409
+ pub struct NotifyViaVisitor ;
410
410
411
411
impl Default for NotifyVia {
412
412
fn default ( ) -> Self {
413
- #[ cfg( not( feature = "desktop" ) ) ]
414
- return NotifyVia :: Bell ;
413
+ Self {
414
+ bell : cfg ! ( not( feature = "desktop" ) ) ,
415
+ #[ cfg( feature = "desktop" ) ]
416
+ desktop : true ,
417
+ }
418
+ }
419
+ }
420
+
421
+ impl < ' de > Visitor < ' de > for NotifyViaVisitor {
422
+ type Value = NotifyVia ;
423
+
424
+ fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
425
+ formatter. write_str ( "a valid notify destination (e.g. \" bell\" or \" desktop\" )" )
426
+ }
427
+
428
+ fn visit_str < E > ( self , value : & str ) -> Result < Self :: Value , E >
429
+ where
430
+ E : SerdeError ,
431
+ {
432
+ let mut via = NotifyVia {
433
+ bell : false ,
434
+ #[ cfg( feature = "desktop" ) ]
435
+ desktop : false ,
436
+ } ;
415
437
416
- #[ cfg( feature = "desktop" ) ]
417
- return NotifyVia :: Desktop ;
438
+ for value in value. split ( '|' ) {
439
+ match value. to_ascii_lowercase ( ) . as_str ( ) {
440
+ "bell" => {
441
+ via. bell = true ;
442
+ } ,
443
+ #[ cfg( feature = "desktop" ) ]
444
+ "desktop" => {
445
+ via. desktop = true ;
446
+ } ,
447
+ #[ cfg( not( feature = "desktop" ) ) ]
448
+ "desktop" => {
449
+ return Err ( E :: custom ( "desktop notification support was compiled out" ) )
450
+ } ,
451
+ _ => return Err ( E :: custom ( "could not parse into a notify destination" ) ) ,
452
+ } ;
453
+ }
454
+
455
+ Ok ( via)
456
+ }
457
+ }
458
+
459
+ impl < ' de > Deserialize < ' de > for NotifyVia {
460
+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
461
+ where
462
+ D : Deserializer < ' de > ,
463
+ {
464
+ deserializer. deserialize_str ( NotifyViaVisitor )
418
465
}
419
466
}
420
467
@@ -1189,6 +1236,29 @@ mod tests {
1189
1236
assert_eq ! ( run, & exp) ;
1190
1237
}
1191
1238
1239
+ #[ test]
1240
+ fn test_parse_notify_via ( ) {
1241
+ assert_eq ! ( NotifyVia { bell: false , desktop: true } , NotifyVia :: default ( ) ) ;
1242
+ assert_eq ! (
1243
+ NotifyVia { bell: false , desktop: true } ,
1244
+ serde_json:: from_str( r#""desktop""# ) . unwrap( )
1245
+ ) ;
1246
+ assert_eq ! (
1247
+ NotifyVia { bell: true , desktop: false } ,
1248
+ serde_json:: from_str( r#""bell""# ) . unwrap( )
1249
+ ) ;
1250
+ assert_eq ! (
1251
+ NotifyVia { bell: true , desktop: true } ,
1252
+ serde_json:: from_str( r#""bell|desktop""# ) . unwrap( )
1253
+ ) ;
1254
+ assert_eq ! (
1255
+ NotifyVia { bell: true , desktop: true } ,
1256
+ serde_json:: from_str( r#""desktop|bell""# ) . unwrap( )
1257
+ ) ;
1258
+ assert ! ( serde_json:: from_str:: <NotifyVia >( r#""other""# ) . is_err( ) ) ;
1259
+ assert ! ( serde_json:: from_str:: <NotifyVia >( r#""""# ) . is_err( ) ) ;
1260
+ }
1261
+
1192
1262
#[ test]
1193
1263
fn test_load_example_config_toml ( ) {
1194
1264
let path = PathBuf :: from ( "config.example.toml" ) ;
0 commit comments