diff --git a/src/lib.rs b/src/lib.rs index 462fc1a..30382d4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,7 @@ mod error; use error::{Error, MpdResult}; use itertools::Itertools; mod structs; -pub use structs::{Position, Stats, Status, Track}; +pub use structs::{Position, Stats, Status, Track, State}; /// some unprintable character to separate repeated keys const SEPARATOR: char = '\x02'; @@ -202,7 +202,7 @@ OK"; playlist: 6, playlistlength: 5364, mixrampdb: 0.0, - state: String::from("play"), + state: State::Play, song: Some(3833), songid: Some(3834), elapsed: Some(Duration::from_secs_f64(69.642)), diff --git a/src/structs.rs b/src/structs.rs index f2e544e..ef277ad 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -89,8 +89,8 @@ pub struct Status { pub playlist: u32, // mpd returns 0 if there is no current playlist pub playlistlength: u32, - // play, stop, pause. TODO: make an enum - pub state: String, + #[serde(deserialize_with = "de_state")] + pub state: State, pub song: Option, pub songid: Option, pub nextsong: Option, @@ -112,6 +112,20 @@ pub struct Status { pub error: Option, } +#[derive(Deserialize, Clone, Debug, PartialEq)] +pub enum State { + Stop, + Play, + Pause, +} + +// Default implementation so I can derive default for containing structs. +impl Default for State { + fn default() -> Self { + Self::Stop + } +} + /// Database statistics as returned by the `stats` command. #[derive(Deserialize, Clone, Debug, Default, PartialEq)] #[serde(default)] @@ -150,6 +164,20 @@ mod helpers { f64::deserialize(deserializer).map(Duration::from_secs_f64).map(Some) } + /// Deserialize the playback state. + pub fn de_state<'de, D>(deserializer: D) -> Result + where D: de::Deserializer<'de> { + match String::deserialize(deserializer)?.as_ref() { + "play" => Ok(State::Play), + "pause" => Ok(State::Pause), + "stop" => Ok(State::Stop), + s => Err(de::Error::invalid_value( + de::Unexpected::Str(s), + &"expected one of play, pause, or stop", + )), + } + } + pub fn de_string_or_vec<'de, D>(deserializer: D) -> Result, D::Error> where D: de::Deserializer<'de> { String::deserialize(deserializer).map(|s| s.split(SEPARATOR).map(std::string::String::from).collect())