2020-06-21 14:20:35 +02:00
use serde ::de ;
2020-06-20 22:50:33 +02:00
use std ::collections ::HashMap ;
mod error ;
use error ::{ Error , MpdResult } ;
mod structs ;
2020-06-20 23:27:00 +02:00
pub use structs ::{ Position , Track } ;
2020-06-20 22:50:33 +02:00
/// some unprintable character to separate repeated keys
const SEPARATOR : char = '\x02' ;
2020-06-21 14:20:35 +02:00
pub fn deserialize_response < ' a , I : Iterator < Item = & ' a str > , T : de ::DeserializeOwned > ( input : I ) -> MpdResult < T > {
2020-06-20 22:50:33 +02:00
let mut map : HashMap < String , String > = HashMap ::new ( ) ;
for line in input {
if line . starts_with ( " OK " ) {
break ;
} else if let Some ( message ) = line . strip_prefix ( " ACK " ) {
return Err ( Error ::from_str ( message . trim ( ) ) ) ;
}
2020-06-21 14:20:35 +02:00
2020-06-20 22:50:33 +02:00
let mut fields = line . splitn ( 2 , " : " ) ;
match ( fields . next ( ) , fields . next ( ) ) {
( Some ( k ) , Some ( v ) ) = > {
if let Some ( existing ) = map . get_mut ( k ) {
existing . push ( SEPARATOR ) ;
existing . push_str ( v ) ;
} else {
map . insert ( k . to_string ( ) , v . to_string ( ) ) ;
}
}
_ = > panic! ( " invalid response line: {:?} " , line ) ,
}
}
// Eventually, I’d like to use my own deserializer instead of envy
2020-06-21 14:20:35 +02:00
Ok ( envy ::from_iter ( map ) . unwrap ( ) )
2020-06-20 22:50:33 +02:00
}
#[ cfg(test) ]
mod tests {
use super ::* ;
2020-06-21 01:00:29 +02:00
use chrono ::DateTime ;
2020-06-20 22:50:33 +02:00
#[ test ]
fn track_de_test ( ) {
let input_str = " file: American Pie.flac
Last - Modified : 2019 - 12 - 16 T21 :38 :54 Z
Album : American Pie
Artist : Don McLean
Date : 1979
Genre : Rock
Title : American Pie
Track : 1
Time : 512
duration : 512.380
Pos : 1367
Id : 1368
OK " ;
2020-06-21 00:03:06 +02:00
let t : Track = deserialize_response ( input_str . lines ( ) ) . unwrap ( ) ;
2020-06-20 22:50:33 +02:00
assert_eq! (
t ,
Track {
file : " American Pie.flac " . to_string ( ) ,
2020-06-21 01:00:29 +02:00
last_modified : Some ( DateTime ::parse_from_rfc3339 ( " 2019-12-16T21:38:54Z " ) . unwrap ( ) ) ,
2020-06-20 22:50:33 +02:00
album : Some ( " American Pie " . to_string ( ) ) ,
artist : Some ( " Don McLean " . to_string ( ) ) ,
date : Some ( 1979 ) ,
genre : Some ( " Rock " . to_string ( ) ) ,
title : Some ( " American Pie " . to_string ( ) ) ,
2020-06-20 23:27:00 +02:00
track : Some ( Position {
item_position : 1 ,
total_items : None ,
} ) ,
2020-06-20 22:50:33 +02:00
duration : std ::time ::Duration ::from_secs_f64 ( 512.380 ) ,
pos : 1367 ,
id : 1368 ,
.. Track ::default ( )
}
) ;
}
2020-06-20 23:27:00 +02:00
#[ test ]
fn repeated_field_test ( ) {
let input_str = r #" file: 06 Symphonie No. 41 en ut majeur, K. 551 _Jupiter_ I. Allegro Vivace.flac
Last - Modified : 2018 - 11 - 11 T09 :01 :54 Z
Album : Symphonies n ° 40 & n ° 41
AlbumArtist : Wolfgang Amadeus Mozart ; Royal Philharmonic Orchestra , Jane Glover
AlbumArtistSort : Mozart , Wolfgang Amadeus ; Royal Philharmonic Orchestra , Glover , Jane
Artist : Wolfgang Amadeus Mozart
ArtistSort : Mozart , Wolfgang Amadeus
Composer : Wolfgang Amadeus Mozart
Date : 2005
Disc : 1
Disc : 1
MUSICBRAINZ_ALBUMARTISTID : b972f589 - fb0e - 474 e - b64a - 803 b0364fa75
MUSICBRAINZ_ALBUMID : 688 d9252 - f897 - 4 ab6 - 879 d - 5 cb83bb71087
MUSICBRAINZ_ARTISTID : b972f589 - fb0e - 474 e - b64a - 803 b0364fa75
MUSICBRAINZ_RELEASETRACKID : 54 a2632f - fa98 - 3713 - bd75 - d7effc03d0b1
MUSICBRAINZ_TRACKID : 2 dd10dd8 - e8de - 4479 - a092 - 9 a04c2760fd6
OriginalDate : 1993
Title : Symphonie No . 41 en ut majeur , K . 551 " Jupiter " : I . Allegro Vivace
Track : 6
Track : 6
Time : 683
Performer : Royal Philharmonic Orchestra
duration : 682.840
Performer : Jane Glover
Pos : 3439
Id : 3440
OK " #;
2020-06-21 00:03:06 +02:00
let t : Track = deserialize_response ( input_str . lines ( ) ) . unwrap ( ) ;
2020-06-20 23:27:00 +02:00
assert_eq! (
t ,
Track {
file : " 06 Symphonie No. 41 en ut majeur, K. 551 _Jupiter_ I. Allegro Vivace.flac " . to_string ( ) ,
2020-06-21 01:00:29 +02:00
last_modified : Some ( DateTime ::parse_from_rfc3339 ( " 2018-11-11T09:01:54Z " ) . unwrap ( ) ) ,
2020-06-20 23:27:00 +02:00
album : Some ( " Symphonies n°40 & n°41 " . to_string ( ) ) ,
artist : Some ( " Wolfgang Amadeus Mozart " . to_string ( ) ) ,
artist_sort : Some ( " Mozart, Wolfgang Amadeus " . to_string ( ) ) ,
album_artist : Some ( " Wolfgang Amadeus Mozart; Royal Philharmonic Orchestra, Jane Glover " . to_string ( ) ) ,
album_artist_sort : Some ( " Mozart, Wolfgang Amadeus; Royal Philharmonic Orchestra, Glover, Jane " . to_string ( ) ) ,
composer : Some ( " Wolfgang Amadeus Mozart " . to_string ( ) ) ,
date : Some ( 2005 ) ,
original_date : Some ( 1993 ) ,
title : Some ( " Symphonie No. 41 en ut majeur, K. 551 \" Jupiter \" : I. Allegro Vivace " . to_string ( ) ) ,
disc : Some ( Position {
item_position : 1 ,
total_items : Some ( 1 ) ,
} ) ,
track : Some ( Position {
item_position : 6 ,
total_items : Some ( 6 ) ,
} ) ,
duration : std ::time ::Duration ::from_secs_f64 ( 682.840 ) ,
pos : 3439 ,
id : 3440 ,
performers : vec ! [ " Royal Philharmonic Orchestra " . to_string ( ) , " Jane Glover " . to_string ( ) ] ,
musicbrainz_albumartistid : Some ( " b972f589-fb0e-474e-b64a-803b0364fa75 " . to_string ( ) ) ,
musicbrainz_albumid : Some ( " 688d9252-f897-4ab6-879d-5cb83bb71087 " . to_string ( ) ) ,
musicbrainz_artistid : Some ( " b972f589-fb0e-474e-b64a-803b0364fa75 " . to_string ( ) ) ,
musicbrainz_releasetrackid : Some ( " 54a2632f-fa98-3713-bd75-d7effc03d0b1 " . to_string ( ) ) ,
musicbrainz_trackid : Some ( " 2dd10dd8-e8de-4479-a092-9a04c2760fd6 " . to_string ( ) ) ,
.. Track ::default ( )
}
) ;
}
2020-06-20 22:50:33 +02:00
}