Add playlist info
This is also the first occurence of multiple structs in one response. The Itertools.batching approach seems to work quite well.
This commit is contained in:
parent
fe2730a7d6
commit
c374a04417
94
src/lib.rs
94
src/lib.rs
|
@ -2,6 +2,7 @@ use serde::de;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
mod error;
|
mod error;
|
||||||
use error::{Error, MpdResult};
|
use error::{Error, MpdResult};
|
||||||
|
use itertools::Itertools;
|
||||||
mod structs;
|
mod structs;
|
||||||
pub use structs::{Position, Status, Track};
|
pub use structs::{Position, Status, Track};
|
||||||
|
|
||||||
|
@ -34,6 +35,34 @@ pub fn deserialize_response<'a, I: Iterator<Item = &'a str>, T: de::DeserializeO
|
||||||
Ok(envy::from_iter(map).unwrap())
|
Ok(envy::from_iter(map).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_playlist_info<'a, I: Iterator<Item = &'a str>>(input: I) -> MpdResult<Vec<Track>> {
|
||||||
|
input
|
||||||
|
.peekable()
|
||||||
|
.batching(|it| {
|
||||||
|
let mut v = match it.next() {
|
||||||
|
// if the playlist is empty or we’ve reached the end,
|
||||||
|
// the response is only the `OK` line.
|
||||||
|
Some("OK") => return None,
|
||||||
|
// otherwise this is the file attribute and thus the first key-value of this track
|
||||||
|
Some(s) => vec![s],
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
// Only peek here in case we encounter the `file:` line which we still need for the next track.
|
||||||
|
while let Some(l) = it.peek() {
|
||||||
|
if l.starts_with("file:") {
|
||||||
|
return Some(v);
|
||||||
|
}
|
||||||
|
if l.starts_with("OK") {
|
||||||
|
return Some(v);
|
||||||
|
}
|
||||||
|
v.push(it.next().unwrap());
|
||||||
|
}
|
||||||
|
None
|
||||||
|
})
|
||||||
|
.map(|b| deserialize_response(b.into_iter()))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -186,4 +215,69 @@ OK";
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn de_playlist_test() {
|
||||||
|
let input_str = "file: 137 A New World.mp3
|
||||||
|
Last-Modified: 2018-03-07T13:11:43Z
|
||||||
|
Artist: Arata Iiyoshi
|
||||||
|
Title: A New World
|
||||||
|
Album: Pokemon Mystery Dungeon: Explorers of Sky
|
||||||
|
duration: 225.802
|
||||||
|
Pos: 1000
|
||||||
|
Id: 6365
|
||||||
|
file: 139 Thoughts For Friends.mp3
|
||||||
|
Last-Modified: 2018-03-07T13:11:43Z
|
||||||
|
Artist: Arata Iiyoshi
|
||||||
|
Title: Thoughts For Friends
|
||||||
|
Album: Pokemon Mystery Dungeon: Explorers of Sky
|
||||||
|
duration: 66.560
|
||||||
|
Pos: 1001
|
||||||
|
Id: 6366
|
||||||
|
file: 140 A Message On the Wind.mp3
|
||||||
|
Last-Modified: 2018-03-07T13:11:43Z
|
||||||
|
Artist: Arata Iiyoshi
|
||||||
|
Title: A Message On the Wind
|
||||||
|
Album: Pokemon Mystery Dungeon: Explorers of Sky
|
||||||
|
duration: 50.155
|
||||||
|
Pos: 1002
|
||||||
|
Id: 6367
|
||||||
|
OK";
|
||||||
|
let queue = read_playlist_info(input_str.lines());
|
||||||
|
let first_track = Track {
|
||||||
|
file: "137 A New World.mp3".into(),
|
||||||
|
title: Some("A New World".into()),
|
||||||
|
artist: Some("Arata Iiyoshi".into()),
|
||||||
|
album: Some("Pokemon Mystery Dungeon: Explorers of Sky".into()),
|
||||||
|
last_modified: Some(DateTime::parse_from_rfc3339("2018-03-07T13:11:43Z").unwrap()),
|
||||||
|
duration: Some(Duration::from_secs_f64(225.802)),
|
||||||
|
pos: 1000,
|
||||||
|
id: 6365,
|
||||||
|
..Track::default()
|
||||||
|
};
|
||||||
|
assert_eq!(
|
||||||
|
queue,
|
||||||
|
Ok(vec![
|
||||||
|
first_track.clone(),
|
||||||
|
Track {
|
||||||
|
file: "139 Thoughts For Friends.mp3".into(),
|
||||||
|
title: Some("Thoughts For Friends".into()),
|
||||||
|
duration: Some(Duration::from_secs_f64(66.56)),
|
||||||
|
pos: 1001,
|
||||||
|
id: 6366,
|
||||||
|
..first_track.clone()
|
||||||
|
},
|
||||||
|
Track {
|
||||||
|
file: "140 A Message On the Wind.mp3".into(),
|
||||||
|
title: Some("A Message On the Wind".into()),
|
||||||
|
duration: Some(Duration::from_secs_f64(50.155)),
|
||||||
|
pos: 1002,
|
||||||
|
id: 6367,
|
||||||
|
..first_track
|
||||||
|
},
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
let queue = read_playlist_info("OK".lines());
|
||||||
|
assert_eq!(queue, Ok(vec![]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user