146 lines
4.9 KiB
Rust
146 lines
4.9 KiB
Rust
use serde::de;
|
|
use std::collections::HashMap;
|
|
mod error;
|
|
use error::{Error, MpdResult};
|
|
mod structs;
|
|
pub use structs::{Position, Track};
|
|
|
|
/// some unprintable character to separate repeated keys
|
|
const SEPARATOR: char = '\x02';
|
|
|
|
pub fn deserialize_response<'a, I: Iterator<Item = &'a str>, T: de::DeserializeOwned>(input: I) -> MpdResult<T> {
|
|
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()));
|
|
}
|
|
|
|
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
|
|
Ok(envy::from_iter(map).unwrap())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use chrono::DateTime;
|
|
|
|
#[test]
|
|
fn track_de_test() {
|
|
let input_str = "file: American Pie.flac
|
|
Last-Modified: 2019-12-16T21:38:54Z
|
|
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";
|
|
let t: Track = deserialize_response(input_str.lines()).unwrap();
|
|
assert_eq!(
|
|
t,
|
|
Track {
|
|
file: "American Pie.flac".to_string(),
|
|
last_modified: Some(DateTime::parse_from_rfc3339("2019-12-16T21:38:54Z").unwrap()),
|
|
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()),
|
|
track: Some(Position {
|
|
item_position: 1,
|
|
total_items: None,
|
|
}),
|
|
duration: std::time::Duration::from_secs_f64(512.380),
|
|
pos: 1367,
|
|
id: 1368,
|
|
..Track::default()
|
|
}
|
|
);
|
|
}
|
|
|
|
#[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-11T09:01:54Z
|
|
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-474e-b64a-803b0364fa75
|
|
MUSICBRAINZ_ALBUMID: 688d9252-f897-4ab6-879d-5cb83bb71087
|
|
MUSICBRAINZ_ARTISTID: b972f589-fb0e-474e-b64a-803b0364fa75
|
|
MUSICBRAINZ_RELEASETRACKID: 54a2632f-fa98-3713-bd75-d7effc03d0b1
|
|
MUSICBRAINZ_TRACKID: 2dd10dd8-e8de-4479-a092-9a04c2760fd6
|
|
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"#;
|
|
let t: Track = deserialize_response(input_str.lines()).unwrap();
|
|
assert_eq!(
|
|
t,
|
|
Track {
|
|
file: "06 Symphonie No. 41 en ut majeur, K. 551 _Jupiter_ I. Allegro Vivace.flac".to_string(),
|
|
last_modified: Some(DateTime::parse_from_rfc3339("2018-11-11T09:01:54Z").unwrap()),
|
|
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()
|
|
}
|
|
);
|
|
}
|
|
}
|