Replaced string errors with a proper Error struct. Changed run_command arguments to a slice instead of vector.

This commit is contained in:
Jonas Frei 2017-05-31 19:32:46 +02:00
parent 4ffa94357a
commit 57d7226373
2 changed files with 212 additions and 151 deletions

View File

@ -1,11 +1,10 @@
use serde_json::{self, Value};
use std::collections::HashMap;
use std::error::Error;
use std::io::BufReader;
use std::io::prelude::*;
use std::iter::Iterator;
use std::sync::mpsc::Sender;
use super::Mpv;
use super::{Mpv, Error, ErrorCode};
#[derive(Debug)]
pub struct PlaylistEntry {
@ -16,28 +15,28 @@ pub struct PlaylistEntry {
}
pub trait TypeHandler: Sized {
fn get_value(value: Value) -> Result<Self, String>;
fn get_value(value: Value) -> Result<Self, Error>;
fn as_string(&self) -> String;
}
impl TypeHandler for String {
fn get_value(value: Value) -> Result<String, String> {
fn get_value(value: Value) -> Result<String, Error> {
if let Value::Object(map) = value {
if let Value::String(ref error) = map["error"] {
if error == "success" && map.contains_key("data") {
if let Value::String(ref s) = map["data"] {
Ok(s.to_string())
} else {
Err("Value did not contain a String".to_string())
Err(Error(ErrorCode::ValueDoesNotContainString))
}
} else {
Err(error.to_string())
Err(Error(ErrorCode::MpvError(error.to_string())))
}
} else {
Err("Unexpected value received".to_string())
Err(Error(ErrorCode::UnexpectedValueReceived))
}
} else {
Err("Unexpected value received".to_string())
Err(Error(ErrorCode::UnexpectedValueReceived))
}
}
@ -47,23 +46,23 @@ impl TypeHandler for String {
}
impl TypeHandler for bool {
fn get_value(value: Value) -> Result<bool, String> {
fn get_value(value: Value) -> Result<bool, Error> {
if let Value::Object(map) = value {
if let Value::String(ref error) = map["error"] {
if error == "success" && map.contains_key("data") {
if let Value::Bool(ref b) = map["data"] {
Ok(*b)
} else {
Err("Value did not contain a bool".to_string())
Err(Error(ErrorCode::ValueDoesNotContainBool))
}
} else {
Err(error.to_string())
Err(Error(ErrorCode::MpvError(error.to_string())))
}
} else {
Err("Unexpected value received".to_string())
Err(Error(ErrorCode::UnexpectedValueReceived))
}
} else {
Err("Unexpected value received".to_string())
Err(Error(ErrorCode::UnexpectedValueReceived))
}
}
fn as_string(&self) -> String {
@ -76,23 +75,23 @@ impl TypeHandler for bool {
}
impl TypeHandler for f64 {
fn get_value(value: Value) -> Result<f64, String> {
fn get_value(value: Value) -> Result<f64, Error> {
if let Value::Object(map) = value {
if let Value::String(ref error) = map["error"] {
if error == "success" && map.contains_key("data") {
if let Value::Number(ref num) = map["data"] {
Ok(num.as_f64().unwrap())
} else {
Err("Value did not contain a f64".to_string())
Err(Error(ErrorCode::ValueDoesNotContainF64))
}
} else {
Err(error.to_string())
Err(Error(ErrorCode::MpvError(error.to_string())))
}
} else {
Err("Unexpected value received".to_string())
Err(Error(ErrorCode::UnexpectedValueReceived))
}
} else {
Err("Unexpected value received".to_string())
Err(Error(ErrorCode::UnexpectedValueReceived))
}
}
@ -102,23 +101,23 @@ impl TypeHandler for f64 {
}
impl TypeHandler for usize {
fn get_value(value: Value) -> Result<usize, String> {
fn get_value(value: Value) -> Result<usize, Error> {
if let Value::Object(map) = value {
if let Value::String(ref error) = map["error"] {
if error == "success" && map.contains_key("data") {
if let Value::Number(ref num) = map["data"] {
Ok(num.as_u64().unwrap() as usize)
} else {
Err("Value did not contain an usize".to_string())
Err(Error(ErrorCode::ValueDoesNotContainUsize))
}
} else {
Err(error.to_string())
Err(Error(ErrorCode::MpvError(error.to_string())))
}
} else {
Err("Unexpected value received".to_string())
Err(Error(ErrorCode::UnexpectedValueReceived))
}
} else {
Err("Unexpected value received".to_string())
Err(Error(ErrorCode::UnexpectedValueReceived))
}
}
@ -128,7 +127,7 @@ impl TypeHandler for usize {
}
impl TypeHandler for HashMap<String, String> {
fn get_value(value: Value) -> Result<HashMap<String, String>, String> {
fn get_value(value: Value) -> Result<HashMap<String, String>, Error> {
if let Value::Object(map) = value {
if let Value::String(ref error) = map["error"] {
if error == "success" && map.contains_key("data") {
@ -142,16 +141,16 @@ impl TypeHandler for HashMap<String, String> {
let output_map = output_map;
Ok(output_map)
} else {
Err("Value did not contain a HashMap".to_string())
Err(Error(ErrorCode::ValueDoesNotContainHashMap))
}
} else {
Err(error.to_string())
Err(Error(ErrorCode::MpvError(error.to_string())))
}
} else {
Err("Unexpected value received".to_string())
Err(Error(ErrorCode::UnexpectedValueReceived))
}
} else {
Err("Unexpected value received".to_string())
Err(Error(ErrorCode::UnexpectedValueReceived))
}
}
@ -161,7 +160,7 @@ impl TypeHandler for HashMap<String, String> {
}
impl TypeHandler for Vec<PlaylistEntry> {
fn get_value(value: Value) -> Result<Vec<PlaylistEntry>, String> {
fn get_value(value: Value) -> Result<Vec<PlaylistEntry>, Error> {
if let Value::Object(map) = value {
if let Value::String(ref error) = map["error"] {
if error == "success" && map.contains_key("data") {
@ -190,16 +189,16 @@ impl TypeHandler for Vec<PlaylistEntry> {
let output = output;
Ok(output)
} else {
Err("Value did not contain a playlist".to_string())
Err(Error(ErrorCode::ValueDoesNotContainPlaylist))
}
} else {
Err(error.to_string())
Err(Error(ErrorCode::MpvError(error.to_string())))
}
} else {
Err("Unexpected value received".to_string())
Err(Error(ErrorCode::UnexpectedValueReceived))
}
} else {
Err("Unexpected value received".to_string())
Err(Error(ErrorCode::UnexpectedValueReceived))
}
}
@ -208,16 +207,16 @@ impl TypeHandler for Vec<PlaylistEntry> {
}
}
pub fn get_mpv_property<T: TypeHandler>(instance: &Mpv, property: &str) -> Result<T, String> {
pub fn get_mpv_property<T: TypeHandler>(instance: &Mpv, property: &str) -> Result<T, Error> {
let ipc_string = format!("{{ \"command\": [\"get_property\",\"{}\"] }}\n", property);
match serde_json::from_str::<Value>(&send_command_sync(instance, &ipc_string)) {
Ok(val) => T::get_value(val),
Err(why) => Err(format!("Error while getting property: {}", why)),
Err(why) => Err(Error(ErrorCode::JsonParseError(why.to_string()))),
}
}
pub fn get_mpv_property_string(instance: &Mpv, property: &str) -> Result<String, String> {
pub fn get_mpv_property_string(instance: &Mpv, property: &str) -> Result<String, Error> {
let ipc_string = format!("{{ \"command\": [\"get_property\",\"{}\"] }}\n", property);
match serde_json::from_str::<Value>(&send_command_sync(instance, &ipc_string)) {
Ok(val) => {
@ -230,39 +229,39 @@ pub fn get_mpv_property_string(instance: &Mpv, property: &str) -> Result<String,
Value::String(ref s) => Ok(s.to_string()),
Value::Array(ref array) => Ok(format!("{:?}", array)),
Value::Object(ref map) => Ok(format!("{:?}", map)),
_ => Err("Value contains an unsupported type".to_string()),
_ => Err(Error(ErrorCode::UnsupportedType)),
}
} else {
Err(error.to_string())
Err(Error(ErrorCode::MpvError(error.to_string())))
}
} else {
Err("Unexpected value received".to_string())
Err(Error(ErrorCode::UnexpectedValueReceived))
}
} else {
Err("Unexpected value received".to_string())
Err(Error(ErrorCode::UnexpectedValueReceived))
}
}
Err(why) => Err(format!("Error while getting property: {}", why)),
Err(why) => Err(Error(ErrorCode::JsonParseError(why.to_string()))),
}
}
pub fn set_mpv_property<T: TypeHandler>(instance: &Mpv,
property: &str,
value: T)
-> Result<(), String> {
-> Result<(), Error> {
let ipc_string = format!("{{ \"command\": [\"set_property\", \"{}\", {}] }}\n",
property,
value.as_string());
match serde_json::from_str::<Value>(&send_command_sync(instance, &ipc_string)) {
Ok(_) => Ok(()),
Err(why) => Err(why.description().to_string()),
Err(why) => Err(Error(ErrorCode::JsonParseError(why.to_string()))),
}
}
pub fn run_mpv_command(instance: &Mpv, command: &str, args: &Vec<&str>) -> Result<(), String> {
pub fn run_mpv_command(instance: &Mpv, command: &str, args: &[&str]) -> Result<(), Error> {
let mut ipc_string = format!("{{ \"command\": [\"{}\"", command);
if args.len() > 0 {
for arg in args.iter() {
for arg in args {
ipc_string.push_str(&format!(", \"{}\"", arg));
}
}
@ -274,18 +273,17 @@ pub fn run_mpv_command(instance: &Mpv, command: &str, args: &Vec<&str>) -> Resul
if error == "success" {
Ok(())
} else {
Err(error.to_string())
Err(Error(ErrorCode::MpvError(error.to_string())))
}
} else {
//Ok(())
Err("Error: Unexpected result received".to_string())
Err(Error(ErrorCode::UnexpectedResult))
}
}
Err(why) => Err(why.description().to_string()),
Err(why) => Err(Error(ErrorCode::JsonParseError(why.to_string()))),
}
}
pub fn observe_mpv_property(instance: &Mpv, id: &usize, property: &str) -> Result<(), String> {
pub fn observe_mpv_property(instance: &Mpv, id: &usize, property: &str) -> Result<(), Error> {
let ipc_string = format!("{{ \"command\": [\"observe_property\", {}, \"{}\"] }}\n",
id,
property);
@ -295,13 +293,13 @@ pub fn observe_mpv_property(instance: &Mpv, id: &usize, property: &str) -> Resul
if error == "success" {
Ok(())
} else {
Err(error.to_string())
Err(Error(ErrorCode::MpvError(error.to_string())))
}
} else {
Err("Unexpected result received".to_string())
Err(Error(ErrorCode::UnexpectedResult))
}
}
Err(why) => Err(why.description().to_string()),
Err(why) => Err(Error(ErrorCode::JsonParseError(why.to_string()))),
}
}
@ -324,15 +322,23 @@ pub fn listen(instance: &Mpv, tx: &Sender<String>) {
tx.send(name.to_string()).unwrap();
}
}
Err(why) => panic!("{}", why.description().to_string()),
Err(why) => panic!("{}", why.to_string()),
}
response.clear();
}
pub fn listen_raw(instance: &Mpv, tx: &Sender<String>) {
let mut response = String::new();
let mut reader = BufReader::new(instance);
reader.read_line(&mut response).unwrap();
tx.send(response.clone()).unwrap();
response.clear();
}
fn send_command_sync(instance: &Mpv, command: &str) -> String {
let mut stream = instance;
match stream.write_all(command.as_bytes()) {
Err(why) => panic!("Error: Could not write to socket: {}", why.description()),
Err(why) => panic!("Error: Could not write to socket: {}", why),
Ok(_) => {
let mut response = String::new();
{

View File

@ -5,6 +5,7 @@ pub mod ipc;
use ipc::*;
use std::collections::HashMap;
use std::fmt::{self, Display};
use std::os::unix::net::UnixStream;
use std::sync::mpsc::Sender;
@ -35,51 +36,108 @@ pub enum Switch {
Toggle,
}
#[derive(Debug)]
pub enum ErrorCode {
MpvError(String),
JsonParseError(String),
ConnectError(String),
UnexpectedResult,
UnexpectedValueReceived,
UnsupportedType,
ValueDoesNotContainBool,
ValueDoesNotContainF64,
ValueDoesNotContainHashMap,
ValueDoesNotContainPlaylist,
ValueDoesNotContainString,
ValueDoesNotContainUsize,
}
pub struct Playlist(pub Vec<PlaylistEntry>);
#[derive(Debug)]
pub struct Error(pub ErrorCode);
pub trait MpvConnector {
fn connect(socket: &str) -> Result<Mpv, String>;
fn connect(socket: &str) -> Result<Mpv, Error>;
}
impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.0, f)
}
}
impl Display for ErrorCode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ErrorCode::ConnectError(ref msg) => f.write_str(&format!("ConnectError: {}", msg)),
ErrorCode::JsonParseError(ref msg) => f.write_str(&format!("JsonParseError: {}", msg)),
ErrorCode::MpvError(ref msg) => {
f.write_str(&format!("mpv returned an error value: {}", msg))
}
ErrorCode::UnexpectedResult => f.write_str("Unexpected result received"),
ErrorCode::UnexpectedValueReceived => f.write_str("Unexpected value received"),
ErrorCode::UnsupportedType => f.write_str("Unsupported type received"),
ErrorCode::ValueDoesNotContainBool => {
f.write_str("The received value is not of type \'std::bool\'")
}
ErrorCode::ValueDoesNotContainF64 => {
f.write_str("The received value is not of type \'std::f64\'")
}
ErrorCode::ValueDoesNotContainHashMap => {
f.write_str("The received value is not of type \'std::collections::HashMap\'")
}
ErrorCode::ValueDoesNotContainPlaylist => {
f.write_str("The received value is not of type \'mpvipc::Playlist\'")
}
ErrorCode::ValueDoesNotContainString => {
f.write_str("The received value is not of type \'std::string::String\'")
}
ErrorCode::ValueDoesNotContainUsize => {
f.write_str("The received value is not of type \'std::usize\'")
}
}
}
}
impl MpvConnector for Mpv {
fn connect(socket: &str) -> Result<Mpv, String> {
fn connect(socket: &str) -> Result<Mpv, Error> {
match UnixStream::connect(socket) {
Ok(stream) => Ok(stream),
Err(msg) => Err(msg.to_string()),
Err(internal_error) => Err(Error(ErrorCode::ConnectError(internal_error.to_string()))),
}
}
}
pub trait GetPropertyTypeHandler: Sized {
fn get_property_generic(instance: &Mpv, property: &str) -> Result<Self, String>;
fn get_property_generic(instance: &Mpv, property: &str) -> Result<Self, Error>;
}
impl GetPropertyTypeHandler for bool {
fn get_property_generic(instance: &Mpv, property: &str) -> Result<bool, String> {
fn get_property_generic(instance: &Mpv, property: &str) -> Result<bool, Error> {
get_mpv_property::<bool>(instance, property)
}
}
impl GetPropertyTypeHandler for String {
fn get_property_generic(instance: &Mpv, property: &str) -> Result<String, String> {
fn get_property_generic(instance: &Mpv, property: &str) -> Result<String, Error> {
get_mpv_property::<String>(instance, property)
}
}
impl GetPropertyTypeHandler for f64 {
fn get_property_generic(instance: &Mpv, property: &str) -> Result<f64, String> {
fn get_property_generic(instance: &Mpv, property: &str) -> Result<f64, Error> {
get_mpv_property::<f64>(instance, property)
}
}
impl GetPropertyTypeHandler for usize {
fn get_property_generic(instance: &Mpv, property: &str) -> Result<usize, String> {
fn get_property_generic(instance: &Mpv, property: &str) -> Result<usize, Error> {
get_mpv_property::<usize>(instance, property)
}
}
impl GetPropertyTypeHandler for Vec<PlaylistEntry> {
fn get_property_generic(instance: &Mpv, property: &str) -> Result<Vec<PlaylistEntry>, String> {
fn get_property_generic(instance: &Mpv, property: &str) -> Result<Vec<PlaylistEntry>, Error> {
get_mpv_property::<Vec<PlaylistEntry>>(instance, property)
}
}
@ -87,42 +145,42 @@ impl GetPropertyTypeHandler for Vec<PlaylistEntry> {
impl GetPropertyTypeHandler for HashMap<String, String> {
fn get_property_generic(instance: &Mpv,
property: &str)
-> Result<HashMap<String, String>, String> {
-> Result<HashMap<String, String>, Error> {
get_mpv_property::<HashMap<String, String>>(instance, property)
}
}
pub trait SetPropertyTypeHandler<T> {
fn set_property_generic(instance: &Mpv, property: &str, value: T) -> Result<(), String>;
fn set_property_generic(instance: &Mpv, property: &str, value: T) -> Result<(), Error>;
}
impl SetPropertyTypeHandler<bool> for bool {
fn set_property_generic(instance: &Mpv, property: &str, value: bool) -> Result<(), String> {
fn set_property_generic(instance: &Mpv, property: &str, value: bool) -> Result<(), Error> {
set_mpv_property::<bool>(instance, property, value)
}
}
impl SetPropertyTypeHandler<String> for String {
fn set_property_generic(instance: &Mpv, property: &str, value: String) -> Result<(), String> {
fn set_property_generic(instance: &Mpv, property: &str, value: String) -> Result<(), Error> {
set_mpv_property::<String>(instance, property, value)
}
}
impl SetPropertyTypeHandler<f64> for f64 {
fn set_property_generic(instance: &Mpv, property: &str, value: f64) -> Result<(), String> {
fn set_property_generic(instance: &Mpv, property: &str, value: f64) -> Result<(), Error> {
set_mpv_property::<f64>(instance, property, value)
}
}
impl SetPropertyTypeHandler<usize> for usize {
fn set_property_generic(instance: &Mpv, property: &str, value: usize) -> Result<(), String> {
fn set_property_generic(instance: &Mpv, property: &str, value: usize) -> Result<(), Error> {
set_mpv_property::<usize>(instance, property, value)
}
}
pub trait Commands {
fn get_metadata(&self) -> Result<HashMap<String, String>, String>;
fn get_playlist(&self) -> Result<Playlist, String>;
fn get_metadata(&self) -> Result<HashMap<String, String>, Error>;
fn get_playlist(&self) -> Result<Playlist, Error>;
/// #Description
///
@ -138,7 +196,6 @@ pub trait Commands {
///
/// ##Input arguments
///
/// - **socket** defines the socket that ipc connects to
/// - **property** defines the mpv property that should be retrieved
///
/// #Example
@ -147,7 +204,7 @@ pub trait Commands {
/// let paused: bool = mpv.get_property("pause").unwrap();
/// let title: String = mpv.get_property("media-title").unwrap();
/// ```
fn get_property<T: GetPropertyTypeHandler>(&self, property: &str) -> Result<T, String>;
fn get_property<T: GetPropertyTypeHandler>(&self, property: &str) -> Result<T, Error>;
/// #Description
///
@ -156,7 +213,6 @@ pub trait Commands {
///
/// ##Input arguments
///
/// - **socket** defines the socket that ipc connects to
/// - **property** defines the mpv property that should be retrieved
///
/// #Example
@ -165,21 +221,22 @@ pub trait Commands {
/// let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
/// let title = mpv.get_property_string("media-title").unwrap();
/// ```
fn get_property_string(&self, property: &str) -> Result<String, String>;
fn kill(&self) -> Result<(), String>;
fn get_property_string(&self, property: &str) -> Result<String, Error>;
fn kill(&self) -> Result<(), Error>;
fn listen(&self, tx: &Sender<String>);
fn next(&self) -> Result<(), String>;
fn observe_property(&self, id: &usize, property: &str) -> Result<(), String>;
fn pause(&self) -> Result<(), String>;
fn playlist_add(&self, file: &str, option: PlaylistAddOptions) -> Result<(), String>;
fn playlist_clear(&self) -> Result<(), String>;
fn playlist_move_id(&self, from: usize, to: usize) -> Result<(), String>;
fn playlist_play_id(&self, id: usize) -> Result<(), String>;
fn playlist_play_next(&self, id: usize) -> Result<(), String>;
fn playlist_shuffle(&self) -> Result<(), String>;
fn playlist_remove_id(&self, id: usize) -> Result<(), String>;
fn prev(&self) -> Result<(), String>;
fn restart(&self) -> Result<(), String>;
fn listen_raw(&self, tx: &Sender<String>);
fn next(&self) -> Result<(), Error>;
fn observe_property(&self, id: &usize, property: &str) -> Result<(), Error>;
fn pause(&self) -> Result<(), Error>;
fn playlist_add(&self, file: &str, option: PlaylistAddOptions) -> Result<(), Error>;
fn playlist_clear(&self) -> Result<(), Error>;
fn playlist_move_id(&self, from: usize, to: usize) -> Result<(), Error>;
fn playlist_play_id(&self, id: usize) -> Result<(), Error>;
fn playlist_play_next(&self, id: usize) -> Result<(), Error>;
fn playlist_shuffle(&self) -> Result<(), Error>;
fn playlist_remove_id(&self, id: usize) -> Result<(), Error>;
fn prev(&self) -> Result<(), Error>;
fn restart(&self) -> Result<(), Error>;
/// #Description
///
@ -190,16 +247,16 @@ pub trait Commands {
/// let mpv = Mpv::connect("/tmp/mpvsocket").unwrap();
///
/// //Run command 'playlist-shuffle' which takes no arguments
/// mpv.run_command("playlist-shuffle", &vec![]);
/// mpv.run_command("playlist-shuffle", &[]);
///
/// //Run command 'seek' which in this case takes two arguments
/// mpv.run_command("seek", &vec!["0", "absolute"]);
/// mpv.run_command("seek", &["0", "absolute"]);
/// ```
fn run_command(&self, command: &str, args: &Vec<&str>) -> Result<(), String>;
fn seek(&self, seconds: f64, option: SeekOptions) -> Result<(), String>;
fn set_loop_file(&self, option: Switch) -> Result<(), String>;
fn set_loop_playlist(&self, option: Switch) -> Result<(), String>;
fn set_mute(&self, option: Switch) -> Result<(), String>;
fn run_command(&self, command: &str, args: &[&str]) -> Result<(), Error>;
fn seek(&self, seconds: f64, option: SeekOptions) -> Result<(), Error>;
fn set_loop_file(&self, option: Switch) -> Result<(), Error>;
fn set_loop_playlist(&self, option: Switch) -> Result<(), Error>;
fn set_mute(&self, option: Switch) -> Result<(), Error>;
/// #Description
///
@ -224,135 +281,133 @@ pub trait Commands {
fn set_property<T: SetPropertyTypeHandler<T>>(&self,
property: &str,
value: T)
-> Result<(), String>;
fn set_speed(&self, input_volume: f64, option: NumberChangeOptions) -> Result<(), String>;
fn set_volume(&self, input_volume: f64, option: NumberChangeOptions) -> Result<(), String>;
fn stop(&self) -> Result<(), String>;
fn toggle(&self) -> Result<(), String>;
-> Result<(), Error>;
fn set_speed(&self, input_volume: f64, option: NumberChangeOptions) -> Result<(), Error>;
fn set_volume(&self, input_volume: f64, option: NumberChangeOptions) -> Result<(), Error>;
fn stop(&self) -> Result<(), Error>;
fn toggle(&self) -> Result<(), Error>;
}
impl Commands for Mpv {
fn get_metadata(&self) -> Result<HashMap<String, String>, String> {
fn get_metadata(&self) -> Result<HashMap<String, String>, Error> {
match get_mpv_property(self, "metadata") {
Ok(map) => Ok(map),
Err(err) => Err(err),
}
}
fn get_playlist(&self) -> Result<Playlist, String> {
fn get_playlist(&self) -> Result<Playlist, Error> {
match get_mpv_property::<Vec<PlaylistEntry>>(self, "playlist") {
Ok(entries) => Ok(Playlist(entries)),
Err(msg) => Err(msg),
}
}
fn get_property<T: GetPropertyTypeHandler>(&self, property: &str) -> Result<T, String> {
fn get_property<T: GetPropertyTypeHandler>(&self, property: &str) -> Result<T, Error> {
T::get_property_generic(self, property)
}
fn get_property_string(&self, property: &str) -> Result<String, String> {
fn get_property_string(&self, property: &str) -> Result<String, Error> {
get_mpv_property_string(self, property)
}
fn kill(&self) -> Result<(), String> {
run_mpv_command(self, "quit", &vec![])
fn kill(&self) -> Result<(), Error> {
run_mpv_command(self, "quit", &[])
}
fn listen(&self, tx: &Sender<String>) {
listen(self, tx);
}
fn next(&self) -> Result<(), String> {
run_mpv_command(self, "playlist-next", &vec![])
fn listen_raw(&self, tx: &Sender<String>) {
listen_raw(self, tx);
}
fn observe_property(&self, id: &usize, property: &str) -> Result<(), String> {
fn next(&self) -> Result<(), Error> {
run_mpv_command(self, "playlist-next", &[])
}
fn observe_property(&self, id: &usize, property: &str) -> Result<(), Error> {
observe_mpv_property(self, id, property)
}
fn pause(&self) -> Result<(), String> {
fn pause(&self) -> Result<(), Error> {
set_mpv_property(self, "pause", true)
}
fn prev(&self) -> Result<(), String> {
run_mpv_command(self, "playlist-prev", &vec![])
fn prev(&self) -> Result<(), Error> {
run_mpv_command(self, "playlist-prev", &[])
}
fn restart(&self) -> Result<(), String> {
run_mpv_command(self, "seek", &vec!["0", "absolute"])
fn restart(&self) -> Result<(), Error> {
run_mpv_command(self, "seek", &["0", "absolute"])
}
fn run_command(&self, command: &str, args: &Vec<&str>) -> Result<(), String> {
fn run_command(&self, command: &str, args: &[&str]) -> Result<(), Error> {
run_mpv_command(self, command, args)
}
fn playlist_add(&self, file: &str, option: PlaylistAddOptions) -> Result<(), String> {
fn playlist_add(&self, file: &str, option: PlaylistAddOptions) -> Result<(), Error> {
match option {
PlaylistAddOptions::Replace => {
run_mpv_command(self, "loadfile", &vec![file, "replace"])
}
PlaylistAddOptions::Append => run_mpv_command(self, "loadfile", &vec![file, "append"]),
PlaylistAddOptions::Replace => run_mpv_command(self, "loadfile", &[file, "replace"]),
PlaylistAddOptions::Append => run_mpv_command(self, "loadfile", &[file, "append"]),
PlaylistAddOptions::AppendPlay => {
run_mpv_command(self, "loadfile", &vec![file, "append-play"])
run_mpv_command(self, "loadfile", &[file, "append-play"])
}
}
}
fn playlist_clear(&self) -> Result<(), String> {
run_mpv_command(self, "playlist-clear", &vec![])
fn playlist_clear(&self) -> Result<(), Error> {
run_mpv_command(self, "playlist-clear", &[])
}
fn playlist_move_id(&self, from: usize, to: usize) -> Result<(), String> {
fn playlist_move_id(&self, from: usize, to: usize) -> Result<(), Error> {
run_mpv_command(self,
"playlist-remove",
&vec![&from.to_string(), &to.to_string()])
&[&from.to_string(), &to.to_string()])
}
fn playlist_play_id(&self, id: usize) -> Result<(), String> {
fn playlist_play_id(&self, id: usize) -> Result<(), Error> {
set_mpv_property(self, "playlist-pos", id)
}
fn playlist_play_next(&self, id: usize) -> Result<(), String> {
fn playlist_play_next(&self, id: usize) -> Result<(), Error> {
match get_mpv_property::<usize>(self, "playlist-pos") {
Ok(current_id) => {
run_mpv_command(self,
"playlist-move",
&vec![&id.to_string(), &(current_id + 1).to_string()])
&[&id.to_string(), &(current_id + 1).to_string()])
}
Err(msg) => Err(msg),
}
}
fn playlist_remove_id(&self, id: usize) -> Result<(), String> {
run_mpv_command(self, "playlist-remove", &vec![&id.to_string()])
fn playlist_remove_id(&self, id: usize) -> Result<(), Error> {
run_mpv_command(self, "playlist-remove", &[&id.to_string()])
}
fn playlist_shuffle(&self) -> Result<(), String> {
run_mpv_command(self, "playlist-shuffle", &vec![])
fn playlist_shuffle(&self) -> Result<(), Error> {
run_mpv_command(self, "playlist-shuffle", &[])
}
fn seek(&self, seconds: f64, option: SeekOptions) -> Result<(), String> {
fn seek(&self, seconds: f64, option: SeekOptions) -> Result<(), Error> {
match option {
SeekOptions::Absolute => {
run_mpv_command(self, "seek", &vec![&seconds.to_string(), "absolute"])
run_mpv_command(self, "seek", &[&seconds.to_string(), "absolute"])
}
SeekOptions::AbsolutePercent => {
run_mpv_command(self,
"seek",
&vec![&seconds.to_string(), "absolute-percent"])
run_mpv_command(self, "seek", &[&seconds.to_string(), "absolute-percent"])
}
SeekOptions::Relative => {
run_mpv_command(self, "seek", &vec![&seconds.to_string(), "relative"])
run_mpv_command(self, "seek", &[&seconds.to_string(), "relative"])
}
SeekOptions::RelativePercent => {
run_mpv_command(self,
"seek",
&vec![&seconds.to_string(), "relative-percent"])
run_mpv_command(self, "seek", &[&seconds.to_string(), "relative-percent"])
}
}
}
fn set_loop_file(&self, option: Switch) -> Result<(), String> {
fn set_loop_file(&self, option: Switch) -> Result<(), Error> {
let mut enabled = false;
match option {
Switch::On => enabled = true,
@ -376,7 +431,7 @@ impl Commands for Mpv {
set_mpv_property(self, "loop-file", enabled)
}
fn set_loop_playlist(&self, option: Switch) -> Result<(), String> {
fn set_loop_playlist(&self, option: Switch) -> Result<(), Error> {
let mut enabled = false;
match option {
Switch::On => enabled = true,
@ -400,7 +455,7 @@ impl Commands for Mpv {
set_mpv_property(self, "loop-playlist", enabled)
}
fn set_mute(&self, option: Switch) -> Result<(), String> {
fn set_mute(&self, option: Switch) -> Result<(), Error> {
let mut enabled = false;
match option {
Switch::On => enabled = true,
@ -420,11 +475,11 @@ impl Commands for Mpv {
fn set_property<T: SetPropertyTypeHandler<T>>(&self,
property: &str,
value: T)
-> Result<(), String> {
-> Result<(), Error> {
T::set_property_generic(self, property, value)
}
fn set_speed(&self, input_speed: f64, option: NumberChangeOptions) -> Result<(), String> {
fn set_speed(&self, input_speed: f64, option: NumberChangeOptions) -> Result<(), Error> {
match get_mpv_property::<f64>(self, "speed") {
Ok(speed) => {
match option {
@ -443,7 +498,7 @@ impl Commands for Mpv {
}
}
fn set_volume(&self, input_volume: f64, option: NumberChangeOptions) -> Result<(), String> {
fn set_volume(&self, input_volume: f64, option: NumberChangeOptions) -> Result<(), Error> {
match get_mpv_property::<f64>(self, "volume") {
Ok(volume) => {
match option {
@ -462,11 +517,11 @@ impl Commands for Mpv {
}
}
fn stop(&self) -> Result<(), String> {
run_mpv_command(self, "stop", &vec![])
fn stop(&self) -> Result<(), Error> {
run_mpv_command(self, "stop", &[])
}
fn toggle(&self) -> Result<(), String> {
fn toggle(&self) -> Result<(), Error> {
match get_mpv_property::<bool>(self, "pause") {
Ok(paused) => set_mpv_property(self, "pause", !paused),
Err(msg) => Err(msg),