Skip to content

Commit dcdfb7a

Browse files
authored
Merge pull request #70 from naglis/handle-duration-from-float-errors
Handle errors when creating duration from float
2 parents d26a58e + fceba21 commit dcdfb7a

File tree

4 files changed

+36
-5
lines changed

4 files changed

+36
-5
lines changed

src/error.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use std::num::{ParseFloatError, ParseIntError};
2020
use std::result;
2121
use std::str::FromStr;
2222
use std::string::ParseError as StringParseError;
23+
use std::time::TryFromFloatSecsError;
2324

2425
// Server errors {{{
2526
/// Server error codes, as defined in [libmpdclient](https://www.musicpd.org/doc/libmpdclient/protocol_8h_source.html)
@@ -219,6 +220,11 @@ impl From<ParseFloatError> for Error {
219220
Error::Parse(ParseError::BadFloat(e))
220221
}
221222
}
223+
impl From<TryFromFloatSecsError> for Error {
224+
fn from(e: TryFromFloatSecsError) -> Error {
225+
Error::Parse(ParseError::BadDuration(e))
226+
}
227+
}
222228
impl From<ServerError> for Error {
223229
fn from(e: ServerError) -> Error {
224230
Error::Server(e)
@@ -235,6 +241,8 @@ pub enum ParseError {
235241
BadInteger(ParseIntError),
236242
/// invalid float
237243
BadFloat(ParseFloatError),
244+
/// invalid duration (negative, too big or not a number)
245+
BadDuration(TryFromFloatSecsError),
238246
/// some other invalid value
239247
BadValue(String),
240248
/// invalid version format (should be x.y.z)
@@ -281,6 +289,7 @@ impl fmt::Display for ParseError {
281289
let desc = match *self {
282290
E::BadInteger(_) => "invalid integer",
283291
E::BadFloat(_) => "invalid float",
292+
E::BadDuration(_) => "invalid duration",
284293
E::BadValue(_) => "invalid value",
285294
E::BadVersion => "invalid version",
286295
E::NotAck => "not an ACK",
@@ -315,6 +324,12 @@ impl From<ParseFloatError> for ParseError {
315324
}
316325
}
317326

327+
impl From<TryFromFloatSecsError> for ParseError {
328+
fn from(e: TryFromFloatSecsError) -> ParseError {
329+
ParseError::BadDuration(e)
330+
}
331+
}
332+
318333
impl From<StringParseError> for ParseError {
319334
fn from(e: StringParseError) -> ParseError {
320335
match e {}

src/song.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ impl FromIter for Song {
119119
"Name" => result.name = Some(line.1.to_owned()),
120120
// Deprecated in MPD.
121121
"Time" => (),
122-
"duration" => result.duration = Some(Duration::from_secs_f64(line.1.parse()?)),
122+
"duration" => result.duration = Some(Duration::try_from_secs_f64(line.1.parse()?)?),
123123
"Range" => result.range = Some(line.1.parse()?),
124124
"Id" => match result.place {
125125
None => result.place = Some(QueuePlace { id: Id(line.1.parse()?), pos: 0, prio: 0 }),

src/status.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,8 @@ impl FromIter for Status {
9898
_ => Ok(None),
9999
}?;
100100
}
101-
// TODO" => float errors don't work on stable
102-
"elapsed" => result.elapsed = line.1.parse::<f32>().ok().map(|v| Duration::from_millis((v * 1000.0) as u64)),
103-
"duration" => result.duration = line.1.parse::<f32>().ok().map(|v| Duration::from_millis((v * 1000.0) as u64)),
101+
"elapsed" => result.elapsed = Some(Duration::try_from_secs_f64(line.1.parse()?)?),
102+
"duration" => result.duration = Some(Duration::try_from_secs_f64(line.1.parse()?)?),
104103
"bitrate" => result.bitrate = Some(line.1.parse()?),
105104
"xfade" => result.crossfade = Some(Duration::from_secs(line.1.parse()?)),
106105
"mixrampdb" => result.mixrampdb = line.1.parse::<f32>()?,

tests/options.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,30 @@ extern crate mpd;
22

33
mod helpers;
44
use helpers::connect;
5+
use mpd::{Idle, Song, State, Subsystem};
56
use std::time::Duration;
67

78
#[test]
89
fn status() {
910
let mut mpd = connect();
1011
let status = mpd.status().unwrap();
11-
println!("{:?}", status);
12+
13+
assert_eq!(status.song, None);
14+
assert_eq!(status.state, State::Stop);
15+
}
16+
17+
#[test]
18+
fn status_during_playback() {
19+
let mut mpd = connect();
20+
mpd.push(Song { file: "silence.flac".to_string(), ..Song::default() }).expect("adding song to queue should not fail");
21+
mpd.play().expect("starting playback should not fail");
22+
mpd.idle(&[Subsystem::Player]).expect("waiting for playback should not fail");
23+
24+
let status = mpd.status().expect("getting status should not fail");
25+
26+
assert!(status.song.is_some());
27+
assert_eq!(status.state, State::Play);
28+
assert_eq!(status.duration, Some(Duration::from_millis(500)));
1229
}
1330

1431
#[test]

0 commit comments

Comments
 (0)