Simplify user code by parsing properties ourselves

This commit is contained in:
Emmanuel Gil Peyrot 2019-06-19 00:30:16 +02:00
parent f02b2549a0
commit 2911b9bb49
3 changed files with 74 additions and 54 deletions

View File

@ -4,6 +4,7 @@ use mpvipc::{
Event, Event,
Mpv, Mpv,
MpvDataType, MpvDataType,
Property,
}; };
use std::io::{self, Write}; use std::io::{self, Write};
@ -31,57 +32,32 @@ fn main() -> Result<(), Error> {
loop { loop {
let event = mpv.event_listen()?; let event = mpv.event_listen()?;
match event { match event {
Event::PropertyChange { name, id: _, data } => { Event::PropertyChange(property) => {
match name.as_ref() { match property {
"path" => { Property::Path(Some(value)) => println!("\nPlaying: {}", value),
match data { Property::Path(None) => (),
MpvDataType::String(value) => println!("\nPlaying: {}", value), Property::Pause(value) => pause = value,
MpvDataType::Null => (), Property::PlaybackTime(Some(value)) => playback_time = value,
_ => panic!("Wrong data type for 'path' value: {:?}", data), Property::PlaybackTime(None) => playback_time = std::f64::NAN,
Property::Duration(Some(value)) => duration = value,
Property::Duration(None) => duration = std::f64::NAN,
Property::Metadata(Some(value)) => {
println!("File tags:");
if let Some(MpvDataType::String(value)) = value.get("ARTIST") {
println!(" Artist: {}", value);
}
if let Some(MpvDataType::String(value)) = value.get("ALBUM") {
println!(" Album: {}", value);
}
if let Some(MpvDataType::String(value)) = value.get("TITLE") {
println!(" Title: {}", value);
}
if let Some(MpvDataType::String(value)) = value.get("TRACK") {
println!(" Track: {}", value);
} }
}, },
"pause" => { Property::Metadata(None) => (),
match data { Property::Unknown { name: _, id: _, data: _ } => (),
MpvDataType::Bool(value) => pause = value,
_ => panic!("Wrong data type for 'pause' value: {:?}", data),
}
},
"playback-time" => {
match data {
MpvDataType::Double(value) => playback_time = value,
MpvDataType::Null => (),
_ => panic!("Wrong data type for 'playback-time' value: {:?}", data),
}
},
"duration" => {
match data {
MpvDataType::Double(value) => duration = value,
MpvDataType::Null => (),
_ => panic!("Wrong data type for 'duration' value: {:?}", data),
}
},
"metadata" => {
match data {
MpvDataType::HashMap(value) => {
println!("File tags:");
if let Some(MpvDataType::String(value)) = value.get("ARTIST") {
println!(" Artist: {}", value);
}
if let Some(MpvDataType::String(value)) = value.get("ALBUM") {
println!(" Album: {}", value);
}
if let Some(MpvDataType::String(value)) = value.get("TITLE") {
println!(" Title: {}", value);
}
if let Some(MpvDataType::String(value)) = value.get("TRACK") {
println!(" Track: {}", value);
}
},
MpvDataType::Null => (),
_ => panic!("Wrong data type for 'metadata' value: {:?}", data),
}
},
_ => panic!("Wrong property changed: {}", name),
} }
}, },
Event::Shutdown => return Ok(()), Event::Shutdown => return Ok(()),

View File

@ -1,4 +1,4 @@
use log::debug; use log::{debug, warn};
use serde_json::{self, Value}; use serde_json::{self, Value};
use std::collections::HashMap; use std::collections::HashMap;
use std::io::BufReader; use std::io::BufReader;
@ -279,6 +279,40 @@ pub fn observe_mpv_property(instance: &Mpv, id: &isize, property: &str) -> Resul
} }
} }
fn try_convert_property(name: &str, id: isize, data: MpvDataType) -> Event {
let property = match name {
"path" => match data {
MpvDataType::String(value) => Property::Path(Some(value)),
MpvDataType::Null => Property::Path(None),
_ => unimplemented!(),
},
"pause" => match data {
MpvDataType::Bool(value) => Property::Pause(value),
_ => unimplemented!(),
},
"playback-time" => match data {
MpvDataType::Double(value) => Property::PlaybackTime(Some(value)),
MpvDataType::Null => Property::PlaybackTime(None),
_ => unimplemented!(),
},
"duration" => match data {
MpvDataType::Double(value) => Property::Duration(Some(value)),
MpvDataType::Null => Property::Duration(None),
_ => unimplemented!(),
},
"metadata" => match data {
MpvDataType::HashMap(value) => Property::Metadata(Some(value)),
MpvDataType::Null => Property::Metadata(None),
_ => unimplemented!(),
},
_ => {
warn!("Property {} not implemented", name);
Property::Unknown { name: name.to_string(), id, data }
}
};
Event::PropertyChange(property)
}
pub fn listen(instance: &mut Mpv) -> Result<Event, Error> { pub fn listen(instance: &mut Mpv) -> Result<Event, Error> {
let mut response = String::new(); let mut response = String::new();
instance.reader.read_line(&mut response).unwrap(); instance.reader.read_line(&mut response).unwrap();
@ -391,7 +425,7 @@ pub fn listen(instance: &mut Mpv) -> Result<Event, Error> {
} }
} }
event = Event::PropertyChange { name, id, data } event = try_convert_property(name.as_ref(), id, data);
} }
_ => { _ => {
event = Event::Unimplemented; event = Event::Unimplemented;

View File

@ -36,13 +36,23 @@ pub enum Event {
MetadataUpdate, MetadataUpdate,
Seek, Seek,
PlaybackRestart, PlaybackRestart,
PropertyChange { PropertyChange(Property),
ChapterChange,
Unimplemented,
}
#[derive(Debug)]
pub enum Property {
Path(Option<String>),
Pause(bool),
PlaybackTime(Option<f64>),
Duration(Option<f64>),
Metadata(Option<HashMap<String, MpvDataType>>),
Unknown {
name: String, name: String,
id: isize, id: isize,
data: MpvDataType, data: MpvDataType,
}, },
ChapterChange,
Unimplemented,
} }
#[derive(Debug)] #[derive(Debug)]