wrap event data in `Option`

This commit is contained in:
Oystein Tveit 2024-05-03 14:02:45 +02:00
parent 712333ab9e
commit 50f19b1f8e
3 changed files with 65 additions and 48 deletions

View File

@ -111,7 +111,7 @@ pub enum Event {
PropertyChange { PropertyChange {
id: usize, id: usize,
name: String, name: String,
data: MpvDataType, data: Option<MpvDataType>,
}, },
EventQueueOverflow, EventQueueOverflow,
None, None,
@ -292,17 +292,11 @@ fn parse_client_message(event: &Map<String, Value>) -> Result<Event, MpvError> {
fn parse_property_change(event: &Map<String, Value>) -> Result<Event, MpvError> { fn parse_property_change(event: &Map<String, Value>) -> Result<Event, MpvError> {
let id = get_key_as!(as_u64, "id", event) as usize; let id = get_key_as!(as_u64, "id", event) as usize;
let property_name = get_key_as!(as_str, "name", event); let property_name = get_key_as!(as_str, "name", event);
let data = event let data = event.get("data").map(|d| json_to_value(d)).transpose()?;
.get("data")
.ok_or(MpvError::MissingKeyInObject {
key: "data".to_owned(),
map: event.clone(),
})?
.clone();
Ok(Event::PropertyChange { Ok(Event::PropertyChange {
id, id,
name: property_name.to_string(), name: property_name.to_string(),
data: json_to_value(&data)?, data: data,
}) })
} }

View File

@ -34,7 +34,7 @@ pub enum Property {
Speed(f64), Speed(f64),
Volume(f64), Volume(f64),
Mute(bool), Mute(bool),
Unknown { name: String, data: MpvDataType }, Unknown { name: String, data: Option<MpvDataType> },
} }
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
@ -58,34 +58,40 @@ pub fn parse_event_property(event: Event) -> Result<(usize, Property), MpvError>
match name.as_str() { match name.as_str() {
"path" => { "path" => {
let path = match data { let path = match data {
MpvDataType::String(s) => Some(s), Some(MpvDataType::String(s)) => Some(s),
MpvDataType::Null => None, Some(MpvDataType::Null) => None,
_ => { Some(data) => {
return Err(MpvError::DataContainsUnexpectedType { return Err(MpvError::DataContainsUnexpectedType {
expected_type: "String".to_owned(), expected_type: "String".to_owned(),
received: data, received: data,
}) })
} }
None => {
return Err(MpvError::MissingMpvData);
}
}; };
Ok((id, Property::Path(path))) Ok((id, Property::Path(path)))
} }
"pause" => { "pause" => {
let pause = match data { let pause = match data {
MpvDataType::Bool(b) => b, Some(MpvDataType::Bool(b)) => b,
_ => { Some(data) => {
return Err(MpvError::DataContainsUnexpectedType { return Err(MpvError::DataContainsUnexpectedType {
expected_type: "bool".to_owned(), expected_type: "bool".to_owned(),
received: data, received: data,
}) })
} }
None => {
return Err(MpvError::MissingMpvData);
}
}; };
Ok((id, Property::Pause(pause))) Ok((id, Property::Pause(pause)))
} }
"playback-time" => { "playback-time" => {
let playback_time = match data { let playback_time = match data {
MpvDataType::Double(d) => Some(d), Some(MpvDataType::Double(d)) => Some(d),
MpvDataType::Null => None, None | Some(MpvDataType::Null) => None,
_ => { Some(data) => {
return Err(MpvError::DataContainsUnexpectedType { return Err(MpvError::DataContainsUnexpectedType {
expected_type: "f64".to_owned(), expected_type: "f64".to_owned(),
received: data, received: data,
@ -96,9 +102,9 @@ pub fn parse_event_property(event: Event) -> Result<(usize, Property), MpvError>
} }
"duration" => { "duration" => {
let duration = match data { let duration = match data {
MpvDataType::Double(d) => Some(d), Some(MpvDataType::Double(d)) => Some(d),
MpvDataType::Null => None, None | Some(MpvDataType::Null) => None,
_ => { Some(data) => {
return Err(MpvError::DataContainsUnexpectedType { return Err(MpvError::DataContainsUnexpectedType {
expected_type: "f64".to_owned(), expected_type: "f64".to_owned(),
received: data, received: data,
@ -109,9 +115,9 @@ pub fn parse_event_property(event: Event) -> Result<(usize, Property), MpvError>
} }
"metadata" => { "metadata" => {
let metadata = match data { let metadata = match data {
MpvDataType::HashMap(m) => Some(m), Some(MpvDataType::HashMap(m)) => Some(m),
MpvDataType::Null => None, None | Some(MpvDataType::Null) => None,
_ => { Some(data) => {
return Err(MpvError::DataContainsUnexpectedType { return Err(MpvError::DataContainsUnexpectedType {
expected_type: "HashMap".to_owned(), expected_type: "HashMap".to_owned(),
received: data, received: data,
@ -130,10 +136,11 @@ pub fn parse_event_property(event: Event) -> Result<(usize, Property), MpvError>
// } // }
"playlist-pos" => { "playlist-pos" => {
let playlist_pos = match data { let playlist_pos = match data {
MpvDataType::Usize(u) => Some(u), Some(MpvDataType::Usize(u)) => Some(u),
MpvDataType::MinusOne => None, Some(MpvDataType::MinusOne) => None,
MpvDataType::Null => None, Some(MpvDataType::Null) => None,
_ => { None => None,
Some(data) => {
return Err(MpvError::DataContainsUnexpectedType { return Err(MpvError::DataContainsUnexpectedType {
expected_type: "usize or -1".to_owned(), expected_type: "usize or -1".to_owned(),
received: data, received: data,
@ -144,76 +151,91 @@ pub fn parse_event_property(event: Event) -> Result<(usize, Property), MpvError>
} }
"loop-file" => { "loop-file" => {
let loop_file = match data.to_owned() { let loop_file = match data.to_owned() {
MpvDataType::Usize(n) => Some(LoopProperty::N(n)), Some(MpvDataType::Usize(n)) => Some(LoopProperty::N(n)),
MpvDataType::Bool(b) => match b { Some(MpvDataType::Bool(b)) => match b {
true => Some(LoopProperty::Inf), true => Some(LoopProperty::Inf),
false => Some(LoopProperty::No), false => Some(LoopProperty::No),
}, },
MpvDataType::String(s) => match s.as_str() { Some(MpvDataType::String(s)) => match s.as_str() {
"inf" => Some(LoopProperty::Inf), "inf" => Some(LoopProperty::Inf),
_ => None, _ => None,
}, },
_ => None, _ => None,
} }
.ok_or(MpvError::DataContainsUnexpectedType { .ok_or(match data {
expected_type: "'inf', bool, or usize".to_owned(), Some(data) => MpvError::DataContainsUnexpectedType {
received: data, expected_type: "'inf', bool, or usize".to_owned(),
received: data,
},
None => MpvError::MissingMpvData,
})?; })?;
Ok((id, Property::LoopFile(loop_file))) Ok((id, Property::LoopFile(loop_file)))
} }
"loop-playlist" => { "loop-playlist" => {
let loop_playlist = match data.to_owned() { let loop_playlist = match data.to_owned() {
MpvDataType::Usize(n) => Some(LoopProperty::N(n)), Some(MpvDataType::Usize(n)) => Some(LoopProperty::N(n)),
MpvDataType::Bool(b) => match b { Some(MpvDataType::Bool(b)) => match b {
true => Some(LoopProperty::Inf), true => Some(LoopProperty::Inf),
false => Some(LoopProperty::No), false => Some(LoopProperty::No),
}, },
MpvDataType::String(s) => match s.as_str() { Some(MpvDataType::String(s)) => match s.as_str() {
"inf" => Some(LoopProperty::Inf), "inf" => Some(LoopProperty::Inf),
_ => None, _ => None,
}, },
_ => None, _ => None,
} }
.ok_or(MpvError::DataContainsUnexpectedType { .ok_or(match data {
expected_type: "'inf', bool, or usize".to_owned(), Some(data) => MpvError::DataContainsUnexpectedType {
received: data, expected_type: "'inf', bool, or usize".to_owned(),
received: data,
},
None => MpvError::MissingMpvData,
})?; })?;
Ok((id, Property::LoopPlaylist(loop_playlist))) Ok((id, Property::LoopPlaylist(loop_playlist)))
} }
"speed" => { "speed" => {
let speed = match data { let speed = match data {
MpvDataType::Double(d) => d, Some(MpvDataType::Double(d)) => d,
_ => { Some(data) => {
return Err(MpvError::DataContainsUnexpectedType { return Err(MpvError::DataContainsUnexpectedType {
expected_type: "f64".to_owned(), expected_type: "f64".to_owned(),
received: data, received: data,
}) })
} }
None => {
return Err(MpvError::MissingMpvData);
}
}; };
Ok((id, Property::Speed(speed))) Ok((id, Property::Speed(speed)))
} }
"volume" => { "volume" => {
let volume = match data { let volume = match data {
MpvDataType::Double(d) => d, Some(MpvDataType::Double(d)) => d,
_ => { Some(data) => {
return Err(MpvError::DataContainsUnexpectedType { return Err(MpvError::DataContainsUnexpectedType {
expected_type: "f64".to_owned(), expected_type: "f64".to_owned(),
received: data, received: data,
}) })
} }
None => {
return Err(MpvError::MissingMpvData);
}
}; };
Ok((id, Property::Volume(volume))) Ok((id, Property::Volume(volume)))
} }
"mute" => { "mute" => {
let mute = match data { let mute = match data {
MpvDataType::Bool(b) => b, Some(MpvDataType::Bool(b)) => b,
_ => { Some(data) => {
return Err(MpvError::DataContainsUnexpectedType { return Err(MpvError::DataContainsUnexpectedType {
expected_type: "bool".to_owned(), expected_type: "bool".to_owned(),
received: data, received: data,
}) })
} }
None => {
return Err(MpvError::MissingMpvData);
}
}; };
Ok((id, Property::Mute(mute))) Ok((id, Property::Mute(mute)))
} }

View File

@ -60,8 +60,9 @@ async fn test_observe_event_successful() {
Err(err) => panic!("{:?}", err), Err(err) => panic!("{:?}", err),
}; };
match data { match data {
MpvDataType::Double(data) => assert_eq!(data, 64.0), Some(MpvDataType::Double(data)) => assert_eq!(data, 64.0),
err => panic!("{:?}", err), Some(data) => panic!("Unexpected value: {:?}", data),
None => panic!("No data"),
} }
}); });