Skip to content

Commit

Permalink
Merge pull request #70 from naglis/handle-duration-from-float-errors
Browse files Browse the repository at this point in the history
Handle errors when creating duration from float
  • Loading branch information
kstep authored Nov 30, 2024
2 parents d26a58e + fceba21 commit dcdfb7a
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 5 deletions.
15 changes: 15 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::num::{ParseFloatError, ParseIntError};
use std::result;
use std::str::FromStr;
use std::string::ParseError as StringParseError;
use std::time::TryFromFloatSecsError;

// Server errors {{{
/// Server error codes, as defined in [libmpdclient](https://www.musicpd.org/doc/libmpdclient/protocol_8h_source.html)
Expand Down Expand Up @@ -219,6 +220,11 @@ impl From<ParseFloatError> for Error {
Error::Parse(ParseError::BadFloat(e))
}
}
impl From<TryFromFloatSecsError> for Error {
fn from(e: TryFromFloatSecsError) -> Error {
Error::Parse(ParseError::BadDuration(e))
}
}
impl From<ServerError> for Error {
fn from(e: ServerError) -> Error {
Error::Server(e)
Expand All @@ -235,6 +241,8 @@ pub enum ParseError {
BadInteger(ParseIntError),
/// invalid float
BadFloat(ParseFloatError),
/// invalid duration (negative, too big or not a number)
BadDuration(TryFromFloatSecsError),
/// some other invalid value
BadValue(String),
/// invalid version format (should be x.y.z)
Expand Down Expand Up @@ -281,6 +289,7 @@ impl fmt::Display for ParseError {
let desc = match *self {
E::BadInteger(_) => "invalid integer",
E::BadFloat(_) => "invalid float",
E::BadDuration(_) => "invalid duration",
E::BadValue(_) => "invalid value",
E::BadVersion => "invalid version",
E::NotAck => "not an ACK",
Expand Down Expand Up @@ -315,6 +324,12 @@ impl From<ParseFloatError> for ParseError {
}
}

impl From<TryFromFloatSecsError> for ParseError {
fn from(e: TryFromFloatSecsError) -> ParseError {
ParseError::BadDuration(e)
}
}

impl From<StringParseError> for ParseError {
fn from(e: StringParseError) -> ParseError {
match e {}
Expand Down
2 changes: 1 addition & 1 deletion src/song.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ impl FromIter for Song {
"Name" => result.name = Some(line.1.to_owned()),
// Deprecated in MPD.
"Time" => (),
"duration" => result.duration = Some(Duration::from_secs_f64(line.1.parse()?)),
"duration" => result.duration = Some(Duration::try_from_secs_f64(line.1.parse()?)?),
"Range" => result.range = Some(line.1.parse()?),
"Id" => match result.place {
None => result.place = Some(QueuePlace { id: Id(line.1.parse()?), pos: 0, prio: 0 }),
Expand Down
5 changes: 2 additions & 3 deletions src/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,8 @@ impl FromIter for Status {
_ => Ok(None),
}?;
}
// TODO" => float errors don't work on stable
"elapsed" => result.elapsed = line.1.parse::<f32>().ok().map(|v| Duration::from_millis((v * 1000.0) as u64)),
"duration" => result.duration = line.1.parse::<f32>().ok().map(|v| Duration::from_millis((v * 1000.0) as u64)),
"elapsed" => result.elapsed = Some(Duration::try_from_secs_f64(line.1.parse()?)?),
"duration" => result.duration = Some(Duration::try_from_secs_f64(line.1.parse()?)?),
"bitrate" => result.bitrate = Some(line.1.parse()?),
"xfade" => result.crossfade = Some(Duration::from_secs(line.1.parse()?)),
"mixrampdb" => result.mixrampdb = line.1.parse::<f32>()?,
Expand Down
19 changes: 18 additions & 1 deletion tests/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,30 @@ extern crate mpd;

mod helpers;
use helpers::connect;
use mpd::{Idle, Song, State, Subsystem};
use std::time::Duration;

#[test]
fn status() {
let mut mpd = connect();
let status = mpd.status().unwrap();
println!("{:?}", status);

assert_eq!(status.song, None);
assert_eq!(status.state, State::Stop);
}

#[test]
fn status_during_playback() {
let mut mpd = connect();
mpd.push(Song { file: "silence.flac".to_string(), ..Song::default() }).expect("adding song to queue should not fail");
mpd.play().expect("starting playback should not fail");
mpd.idle(&[Subsystem::Player]).expect("waiting for playback should not fail");

let status = mpd.status().expect("getting status should not fail");

assert!(status.song.is_some());
assert_eq!(status.state, State::Play);
assert_eq!(status.duration, Some(Duration::from_millis(500)));
}

#[test]
Expand Down

0 comments on commit dcdfb7a

Please sign in to comment.