4
4
//!
5
5
//! [proto]: http://www.musicpd.org/doc/protocol/
6
6
7
- use std:: io:: { Read , Write , BufRead , Lines } ;
7
+ use std:: io:: { BufRead , Lines , Read , Write } ;
8
8
use std:: convert:: From ;
9
9
use std:: fmt:: Arguments ;
10
10
use std:: net:: { TcpStream , ToSocketAddrs } ;
11
11
12
12
use bufstream:: BufStream ;
13
13
use version:: Version ;
14
- use error:: { ProtoError , Error , Result } ;
15
- use status:: { Status , ReplayGain } ;
14
+ use error:: { Error , ProtoError , Result } ;
15
+ use status:: { ReplayGain , Status } ;
16
16
use stats:: Stats ;
17
- use song:: { Song , Id } ;
17
+ use song:: { Id , Song } ;
18
18
use output:: Output ;
19
19
use playlist:: Playlist ;
20
20
use plugin:: Plugin ;
@@ -29,10 +29,12 @@ use proto::*;
29
29
30
30
/// Client connection
31
31
#[ derive( Debug ) ]
32
- pub struct Client < S =TcpStream > where S : Read + Write {
32
+ pub struct Client < S = TcpStream >
33
+ where S : Read + Write
34
+ {
33
35
socket : BufStream < S > ,
34
36
/// MPD version
35
- pub version : Version
37
+ pub version : Version ,
36
38
}
37
39
38
40
impl Default for Client < TcpStream > {
@@ -48,7 +50,7 @@ impl Client<TcpStream> {
48
50
}
49
51
}
50
52
51
- impl < S : Read + Write > Client < S > {
53
+ impl < S : Read + Write > Client < S > {
52
54
// Constructors {{{
53
55
/// Create client from some arbitrary pre-connected socket
54
56
pub fn new ( socket : S ) -> Result < Client < S > > {
@@ -65,7 +67,7 @@ impl<S: Read+Write> Client<S> {
65
67
66
68
Ok ( Client {
67
69
socket : socket,
68
- version : version
70
+ version : version,
69
71
} )
70
72
}
71
73
// }}}
@@ -231,22 +233,26 @@ impl<S: Read+Write> Client<S> {
231
233
pub fn push < P : AsRef < str > > ( & mut self , path : P ) -> Result < Id > {
232
234
self . run_command_fmt ( format_args ! ( "addid \" {}\" " , path. as_ref( ) ) )
233
235
. and_then ( |_| self . read_field ( "Id" ) )
234
- . and_then ( |v| self . expect_ok ( )
235
- . and_then ( |_| v. parse ( ) . map_err ( From :: from) . map ( Id ) ) )
236
+ . and_then ( |v| {
237
+ self . expect_ok ( )
238
+ . and_then ( |_| v. parse ( ) . map_err ( From :: from) . map ( Id ) )
239
+ } )
236
240
}
237
241
238
242
/// Insert a song into a given position in a queue
239
243
pub fn insert < P : AsRef < str > > ( & mut self , path : P , pos : usize ) -> Result < usize > {
240
244
self . run_command_fmt ( format_args ! ( "addid \" {}\" {}" , path. as_ref( ) , pos) )
241
245
. and_then ( |_| self . read_field ( "Id" ) )
242
- . and_then ( |v| self . expect_ok ( )
243
- . and_then ( |_| v. parse ( ) . map_err ( From :: from) ) )
246
+ . and_then ( |v| {
247
+ self . expect_ok ( )
248
+ . and_then ( |_| v. parse ( ) . map_err ( From :: from) )
249
+ } )
244
250
}
245
251
246
252
/// Delete a song (at some position) or several songs (in a range) from a queue
247
253
pub fn delete < T : ToQueueRangeOrPlace > ( & mut self , pos : T ) -> Result < ( ) > {
248
- self . run_command_fmt ( format_args ! ( "delete{} {}" , if T :: is_id( ) { "id" } else { "" } , pos. to_range( ) ) )
249
- . and_then ( |_| self . expect_ok ( ) )
254
+ self . run_command_fmt ( format_args ! ( "delete{} {}" , if T :: is_id( ) { "id" } else { "" } , pos. to_range( ) ) )
255
+ . and_then ( |_| self . expect_ok ( ) )
250
256
}
251
257
252
258
/// Move a song (at a some position) or several songs (in a range) to other position in queue
@@ -312,7 +318,8 @@ impl<S: Read+Write> Client<S> {
312
318
313
319
/// Login to MPD server with given password
314
320
pub fn login ( & mut self , password : & str ) -> Result < ( ) > {
315
- self . run_command_fmt ( format_args ! ( "password \" {}\" " , password) ) . and_then ( |_| self . expect_ok ( ) )
321
+ self . run_command_fmt ( format_args ! ( "password \" {}\" " , password) )
322
+ . and_then ( |_| self . expect_ok ( ) )
316
323
}
317
324
// }}}
318
325
@@ -389,16 +396,20 @@ impl<S: Read+Write> Client<S> {
389
396
pub fn rescan ( & mut self ) -> Result < u32 > {
390
397
self . run_command ( "rescan" )
391
398
. and_then ( |_| self . read_field ( "updating_db" ) )
392
- . and_then ( |v| self . expect_ok ( )
393
- . and_then ( |_| v. parse ( ) . map_err ( From :: from) ) )
399
+ . and_then ( |v| {
400
+ self . expect_ok ( )
401
+ . and_then ( |_| v. parse ( ) . map_err ( From :: from) )
402
+ } )
394
403
}
395
404
396
405
/// Run database update, i.e. remove non-existing files from DB
397
406
pub fn update ( & mut self ) -> Result < u32 > {
398
407
self . run_command ( "update" )
399
408
. and_then ( |_| self . read_field ( "updating_db" ) )
400
- . and_then ( |v| self . expect_ok ( )
401
- . and_then ( |_| v. parse ( ) . map_err ( From :: from) ) )
409
+ . and_then ( |v| {
410
+ self . expect_ok ( )
411
+ . and_then ( |_| v. parse ( ) . map_err ( From :: from) )
412
+ } )
402
413
}
403
414
// }}}
404
415
@@ -457,41 +468,61 @@ impl<S: Read+Write> Client<S> {
457
468
/// List all available commands
458
469
pub fn commands ( & mut self ) -> Result < Vec < String > > {
459
470
self . run_command ( "commands" )
460
- . and_then ( |_| self . read_pairs ( )
461
- . filter ( |r| r. as_ref ( )
462
- . map ( |& ( ref a, _) | * a == "command" ) . unwrap_or ( true ) )
463
- . map ( |r| r. map ( |( _, b) | b) )
464
- . collect ( ) )
471
+ . and_then ( |_| {
472
+ self . read_pairs ( )
473
+ . filter ( |r| {
474
+ r. as_ref ( )
475
+ . map ( |& ( ref a, _) | * a == "command" )
476
+ . unwrap_or ( true )
477
+ } )
478
+ . map ( |r| r. map ( |( _, b) | b) )
479
+ . collect ( )
480
+ } )
465
481
}
466
482
467
483
/// List all forbidden commands
468
484
pub fn notcommands ( & mut self ) -> Result < Vec < String > > {
469
485
self . run_command ( "notcommands" )
470
- . and_then ( |_| self . read_pairs ( )
471
- . filter ( |r| r. as_ref ( )
472
- . map ( |& ( ref a, _) | * a == "command" ) . unwrap_or ( true ) )
473
- . map ( |r| r. map ( |( _, b) | b) )
474
- . collect ( ) )
486
+ . and_then ( |_| {
487
+ self . read_pairs ( )
488
+ . filter ( |r| {
489
+ r. as_ref ( )
490
+ . map ( |& ( ref a, _) | * a == "command" )
491
+ . unwrap_or ( true )
492
+ } )
493
+ . map ( |r| r. map ( |( _, b) | b) )
494
+ . collect ( )
495
+ } )
475
496
}
476
497
477
498
/// List all available URL handlers
478
499
pub fn urlhandlers ( & mut self ) -> Result < Vec < String > > {
479
500
self . run_command ( "urlhandlers" )
480
- . and_then ( |_| self . read_pairs ( )
481
- . filter ( |r| r. as_ref ( )
482
- . map ( |& ( ref a, _) | * a == "handler" ) . unwrap_or ( true ) )
483
- . map ( |r| r. map ( |( _, b) | b) )
484
- . collect ( ) )
501
+ . and_then ( |_| {
502
+ self . read_pairs ( )
503
+ . filter ( |r| {
504
+ r. as_ref ( )
505
+ . map ( |& ( ref a, _) | * a == "handler" )
506
+ . unwrap_or ( true )
507
+ } )
508
+ . map ( |r| r. map ( |( _, b) | b) )
509
+ . collect ( )
510
+ } )
485
511
}
486
512
487
513
/// List all supported tag types
488
514
pub fn tagtypes ( & mut self ) -> Result < Vec < String > > {
489
515
self . run_command ( "tagtypes" )
490
- . and_then ( |_| self . read_pairs ( )
491
- . filter ( |r| r. as_ref ( )
492
- . map ( |& ( ref a, _) | * a == "tagtype" ) . unwrap_or ( true ) )
493
- . map ( |r| r. map ( |( _, b) | b) )
494
- . collect ( ) )
516
+ . and_then ( |_| {
517
+ self . read_pairs ( )
518
+ . filter ( |r| {
519
+ r. as_ref ( )
520
+ . map ( |& ( ref a, _) | * a == "tagtype" )
521
+ . unwrap_or ( true )
522
+ } )
523
+ . map ( |r| r. map ( |( _, b) | b) )
524
+ . collect ( )
525
+ } )
495
526
}
496
527
497
528
/// List all available decoder plugins
@@ -509,12 +540,16 @@ impl<S: Read+Write> Client<S> {
509
540
plugin = Some ( Plugin {
510
541
name : b,
511
542
suffixes : Vec :: new ( ) ,
512
- mime_types : Vec :: new ( )
543
+ mime_types : Vec :: new ( ) ,
513
544
} ) ;
514
- } ,
515
- "mime_type" => { plugin. as_mut ( ) . map ( |p| p. mime_types . push ( b) ) ; }
516
- "suffix" => { plugin. as_mut ( ) . map ( |p| p. suffixes . push ( b) ) ; }
517
- _ => unreachable ! ( )
545
+ }
546
+ "mime_type" => {
547
+ plugin. as_mut ( ) . map ( |p| p. mime_types . push ( b) ) ;
548
+ }
549
+ "suffix" => {
550
+ plugin. as_mut ( ) . map ( |p| p. suffixes . push ( b) ) ;
551
+ }
552
+ _ => unreachable ! ( ) ,
518
553
}
519
554
}
520
555
plugin. map ( |p| result. push ( p) ) ;
@@ -526,11 +561,16 @@ impl<S: Read+Write> Client<S> {
526
561
/// List all channels available for current connection
527
562
pub fn channels ( & mut self ) -> Result < Vec < Channel > > {
528
563
self . run_command ( "channels" )
529
- . and_then ( |_| self . read_pairs ( )
530
- . filter ( |r| r. as_ref ( )
531
- . map ( |& ( ref a, _) | * a == "channel" ) . unwrap_or ( true ) )
532
- . map ( |r| r. map ( |( _, b) | unsafe { Channel :: new_unchecked ( b) } ) )
533
- . collect ( ) )
564
+ . and_then ( |_| {
565
+ self . read_pairs ( )
566
+ . filter ( |r| {
567
+ r. as_ref ( )
568
+ . map ( |& ( ref a, _) | * a == "channel" )
569
+ . unwrap_or ( true )
570
+ } )
571
+ . map ( |r| r. map ( |( _, b) | unsafe { Channel :: new_unchecked ( b) } ) )
572
+ . collect ( )
573
+ } )
534
574
}
535
575
536
576
/// Read queued messages from subscribed channels
@@ -619,39 +659,57 @@ impl<S: Read+Write> Client<S> {
619
659
/// List all stickers from a given object, identified by type and uri
620
660
pub fn stickers ( & mut self , typ : & str , uri : & str ) -> Result < Vec < String > > {
621
661
self . run_command_fmt ( format_args ! ( "sticker list {} \" {}\" " , typ, uri) )
622
- . and_then ( |_| self . read_pairs ( )
623
- . filter ( |r| r. as_ref ( )
624
- . map ( |& ( ref a, _) | * a == "sticker" ) . unwrap_or ( true ) )
625
- . map ( |r| r. map ( |( _, b) | b. splitn ( 2 , "=" ) . nth ( 1 ) . map ( |s| s. to_owned ( ) ) . unwrap ( ) ) )
626
- . collect ( ) )
662
+ . and_then ( |_| {
663
+ self . read_pairs ( )
664
+ . filter ( |r| {
665
+ r. as_ref ( )
666
+ . map ( |& ( ref a, _) | * a == "sticker" )
667
+ . unwrap_or ( true )
668
+ } )
669
+ . map ( |r| r. map ( |( _, b) | b. splitn ( 2 , "=" ) . nth ( 1 ) . map ( |s| s. to_owned ( ) ) . unwrap ( ) ) )
670
+ . collect ( )
671
+ } )
627
672
}
628
673
629
674
/// List all (file, sticker) pairs for sticker name and objects of given type
630
675
/// from given directory (identified by uri)
631
676
pub fn find_sticker ( & mut self , typ : & str , uri : & str , name : & str ) -> Result < Vec < ( String , String ) > > {
632
677
self . run_command_fmt ( format_args ! ( "sticker find {} \" {}\" {}" , typ, uri, name) )
633
- . and_then ( |_| self . read_pairs ( ) . split ( "file" ) . map ( |rmap| rmap. map ( |mut map|
634
- ( map. remove ( "file" ) . unwrap ( ) ,
635
- map. remove ( "sticker" ) . and_then ( |s| s. splitn ( 2 , "=" ) . nth ( 1 ) . map ( |s| s. to_owned ( ) ) ) . unwrap ( ) ) ) )
636
- . collect ( ) )
678
+ . and_then ( |_| {
679
+ self . read_pairs ( )
680
+ . split ( "file" )
681
+ . map ( |rmap| {
682
+ rmap. map ( |mut map| {
683
+ ( map. remove ( "file" ) . unwrap ( ) ,
684
+ map. remove ( "sticker" )
685
+ . and_then ( |s| s. splitn ( 2 , "=" ) . nth ( 1 ) . map ( |s| s. to_owned ( ) ) )
686
+ . unwrap ( ) )
687
+ } )
688
+ } )
689
+ . collect ( )
690
+ } )
637
691
}
638
692
639
693
/// List all files of a given type under given directory (identified by uri)
640
694
/// with a tag set to given value
641
695
pub fn find_sticker_eq ( & mut self , typ : & str , uri : & str , name : & str , value : & str ) -> Result < Vec < String > > {
642
696
self . run_command_fmt ( format_args ! ( "sticker find {} \" {}\" {} = \" {}\" " , typ, uri, name, value) )
643
- . and_then ( |_| self . read_pairs ( )
644
- . filter ( |r| r. as_ref ( )
645
- . map ( |& ( ref a, _) | * a == "file" ) . unwrap_or ( true ) )
646
- . map ( |r| r. map ( |( _, b) | b) )
647
- . collect ( ) )
697
+ . and_then ( |_| {
698
+ self . read_pairs ( )
699
+ . filter ( |r| {
700
+ r. as_ref ( )
701
+ . map ( |& ( ref a, _) | * a == "file" )
702
+ . unwrap_or ( true )
703
+ } )
704
+ . map ( |r| r. map ( |( _, b) | b) )
705
+ . collect ( )
706
+ } )
648
707
}
649
708
// }}}
650
-
651
709
}
652
710
653
711
// Helper methods {{{
654
- impl < S : Read + Write > Proto for Client < S > {
712
+ impl < S : Read + Write > Proto for Client < S > {
655
713
type Stream = S ;
656
714
657
715
fn read_line ( & mut self ) -> Result < String > {
@@ -668,14 +726,16 @@ impl<S: Read+Write> Proto for Client<S> {
668
726
}
669
727
670
728
fn run_command ( & mut self , command : & str ) -> Result < ( ) > {
671
- self . socket . write_all ( command. as_bytes ( ) )
729
+ self . socket
730
+ . write_all ( command. as_bytes ( ) )
672
731
. and_then ( |_| self . socket . write ( & [ 0x0a ] ) )
673
732
. and_then ( |_| self . socket . flush ( ) )
674
733
. map_err ( From :: from)
675
734
}
676
735
677
736
fn run_command_fmt ( & mut self , command : Arguments ) -> Result < ( ) > {
678
- self . socket . write_fmt ( command)
737
+ self . socket
738
+ . write_fmt ( command)
679
739
. and_then ( |_| self . socket . write ( & [ 0x0a ] ) )
680
740
. and_then ( |_| self . socket . flush ( ) )
681
741
. map_err ( From :: from)
@@ -684,4 +744,3 @@ impl<S: Read+Write> Proto for Client<S> {
684
744
// }}}
685
745
686
746
// }}}
687
-
0 commit comments