From 57d72263738743cd878c974b05a9220bb7357030 Mon Sep 17 00:00:00 2001 From: Jonas Frei Date: Wed, 31 May 2017 19:32:46 +0200 Subject: [PATCH] Replaced string errors with a proper Error struct. Changed run_command arguments to a slice instead of vector. --- src/ipc.rs | 116 +++++++++++++------------ src/lib.rs | 247 ++++++++++++++++++++++++++++++++--------------------- 2 files changed, 212 insertions(+), 151 deletions(-) diff --git a/src/ipc.rs b/src/ipc.rs index a555c07..e6d85ed 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -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; + fn get_value(value: Value) -> Result; fn as_string(&self) -> String; } impl TypeHandler for String { - fn get_value(value: Value) -> Result { + fn get_value(value: Value) -> Result { 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 { + fn get_value(value: Value) -> Result { 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 { + fn get_value(value: Value) -> Result { 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 { + fn get_value(value: Value) -> Result { 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 { - fn get_value(value: Value) -> Result, String> { + fn get_value(value: Value) -> Result, 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 { 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 { } impl TypeHandler for Vec { - fn get_value(value: Value) -> Result, String> { + fn get_value(value: Value) -> Result, 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 { 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 { } } -pub fn get_mpv_property(instance: &Mpv, property: &str) -> Result { +pub fn get_mpv_property(instance: &Mpv, property: &str) -> Result { let ipc_string = format!("{{ \"command\": [\"get_property\",\"{}\"] }}\n", property); match serde_json::from_str::(&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 { +pub fn get_mpv_property_string(instance: &Mpv, property: &str) -> Result { let ipc_string = format!("{{ \"command\": [\"get_property\",\"{}\"] }}\n", property); match serde_json::from_str::(&send_command_sync(instance, &ipc_string)) { Ok(val) => { @@ -230,39 +229,39 @@ pub fn get_mpv_property_string(instance: &Mpv, property: &str) -> Result 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(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::(&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) { 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) { + 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(); { diff --git a/src/lib.rs b/src/lib.rs index 2b602ab..137c09b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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); +#[derive(Debug)] +pub struct Error(pub ErrorCode); pub trait MpvConnector { - fn connect(socket: &str) -> Result; + fn connect(socket: &str) -> Result; +} + +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 { + fn connect(socket: &str) -> Result { 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; + fn get_property_generic(instance: &Mpv, property: &str) -> Result; } impl GetPropertyTypeHandler for bool { - fn get_property_generic(instance: &Mpv, property: &str) -> Result { + fn get_property_generic(instance: &Mpv, property: &str) -> Result { get_mpv_property::(instance, property) } } impl GetPropertyTypeHandler for String { - fn get_property_generic(instance: &Mpv, property: &str) -> Result { + fn get_property_generic(instance: &Mpv, property: &str) -> Result { get_mpv_property::(instance, property) } } impl GetPropertyTypeHandler for f64 { - fn get_property_generic(instance: &Mpv, property: &str) -> Result { + fn get_property_generic(instance: &Mpv, property: &str) -> Result { get_mpv_property::(instance, property) } } impl GetPropertyTypeHandler for usize { - fn get_property_generic(instance: &Mpv, property: &str) -> Result { + fn get_property_generic(instance: &Mpv, property: &str) -> Result { get_mpv_property::(instance, property) } } impl GetPropertyTypeHandler for Vec { - fn get_property_generic(instance: &Mpv, property: &str) -> Result, String> { + fn get_property_generic(instance: &Mpv, property: &str) -> Result, Error> { get_mpv_property::>(instance, property) } } @@ -87,42 +145,42 @@ impl GetPropertyTypeHandler for Vec { impl GetPropertyTypeHandler for HashMap { fn get_property_generic(instance: &Mpv, property: &str) - -> Result, String> { + -> Result, Error> { get_mpv_property::>(instance, property) } } pub trait SetPropertyTypeHandler { - 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 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::(instance, property, value) } } impl SetPropertyTypeHandler 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::(instance, property, value) } } impl SetPropertyTypeHandler 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::(instance, property, value) } } impl SetPropertyTypeHandler 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::(instance, property, value) } } pub trait Commands { - fn get_metadata(&self) -> Result, String>; - fn get_playlist(&self) -> Result; + fn get_metadata(&self) -> Result, Error>; + fn get_playlist(&self) -> Result; /// #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(&self, property: &str) -> Result; + fn get_property(&self, property: &str) -> Result; /// #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; - fn kill(&self) -> Result<(), String>; + fn get_property_string(&self, property: &str) -> Result; + fn kill(&self) -> Result<(), Error>; fn listen(&self, tx: &Sender); - 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); + 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>(&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, String> { + fn get_metadata(&self) -> Result, Error> { match get_mpv_property(self, "metadata") { Ok(map) => Ok(map), Err(err) => Err(err), } } - fn get_playlist(&self) -> Result { + fn get_playlist(&self) -> Result { match get_mpv_property::>(self, "playlist") { Ok(entries) => Ok(Playlist(entries)), Err(msg) => Err(msg), } } - fn get_property(&self, property: &str) -> Result { + fn get_property(&self, property: &str) -> Result { T::get_property_generic(self, property) } - fn get_property_string(&self, property: &str) -> Result { + fn get_property_string(&self, property: &str) -> Result { 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) { listen(self, tx); } - fn next(&self) -> Result<(), String> { - run_mpv_command(self, "playlist-next", &vec![]) + fn listen_raw(&self, tx: &Sender) { + 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::(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>(&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::(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::(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::(self, "pause") { Ok(paused) => set_mpv_property(self, "pause", !paused), Err(msg) => Err(msg),