Replaced string errors with a proper Error struct. Changed run_command arguments to a slice instead of vector.
This commit is contained in:
parent
4ffa94357a
commit
57d7226373
116
src/ipc.rs
116
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<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();
|
||||
{
|
||||
|
|
247
src/lib.rs
247
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<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),
|
||||
|
|
Loading…
Reference in New Issue