From a0888b93861ee6bea7ea2341e57f38be9bb25258 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Tue, 30 Apr 2024 00:41:16 +0200 Subject: [PATCH] api: move highlevel functions into extension --- examples/fetch_state.rs | 2 +- examples/media_player.rs | 2 +- src/api.rs | 257 +------------------------------------ src/api_extension.rs | 269 +++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 + tests/events.rs | 2 +- tests/get_property.rs | 2 +- tests/set_property.rs | 2 +- 8 files changed, 277 insertions(+), 261 deletions(-) create mode 100644 src/api_extension.rs diff --git a/examples/fetch_state.rs b/examples/fetch_state.rs index 63b9619..ba4063d 100644 --- a/examples/fetch_state.rs +++ b/examples/fetch_state.rs @@ -1,5 +1,5 @@ use env_logger; -use mpvipc::{Error as MpvError, Mpv}; +use mpvipc::{Error as MpvError, Mpv, MpvExt}; #[tokio::main] async fn main() -> Result<(), MpvError> { diff --git a/examples/media_player.rs b/examples/media_player.rs index 70ffd20..cfa0ee8 100644 --- a/examples/media_player.rs +++ b/examples/media_player.rs @@ -1,5 +1,5 @@ use env_logger; -use mpvipc::{Error, Event, Mpv, MpvDataType, Property}; +use mpvipc::{Error, Event, Mpv, MpvExt, MpvDataType, Property}; use std::io::{self, Write}; fn seconds_to_hms(total: f64) -> String { diff --git a/src/api.rs b/src/api.rs index 6382575..5a9892f 100644 --- a/src/api.rs +++ b/src/api.rs @@ -83,7 +83,7 @@ pub enum MpvCommand { Unobserve(isize), } -trait IntoRawCommandPart { +pub(crate) trait IntoRawCommandPart { fn into_raw_command_part(self) -> String; } @@ -99,23 +99,6 @@ pub enum MpvDataType { Usize(usize), } -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum NumberChangeOptions { - Absolute, - Increase, - Decrease, -} - -impl IntoRawCommandPart for NumberChangeOptions { - fn into_raw_command_part(self) -> String { - match self { - NumberChangeOptions::Absolute => "absolute".to_string(), - NumberChangeOptions::Increase => "increase".to_string(), - NumberChangeOptions::Decrease => "decrease".to_string(), - } - } -} - #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub enum PlaylistAddOptions { Replace, @@ -156,13 +139,6 @@ impl IntoRawCommandPart for SeekOptions { } } -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] -pub enum Switch { - On, - Off, - Toggle, -} - #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum ErrorCode { MpvError(String), @@ -457,16 +433,6 @@ impl Mpv { }) } - pub async fn get_metadata(&self) -> Result, Error> { - self.get_property("metadata").await - } - - pub async fn get_playlist(&self) -> Result { - self.get_property::>("playlist") - .await - .map(|entries| Playlist(entries)) - } - /// # Description /// /// Retrieves the property value from mpv. @@ -537,63 +503,6 @@ impl Mpv { } } - pub async fn kill(&self) -> Result<(), Error> { - self.run_command(MpvCommand::Quit).await - } - - /// # Description - /// - /// Waits until an mpv event occurs and returns the Event. - /// - /// # Example - /// - /// ```ignore - /// let mut mpv = Mpv::connect("/tmp/mpvsocket")?; - /// loop { - /// let event = mpv.event_listen()?; - /// println!("{:?}", event); - /// } - /// ``` - // pub fn event_listen(&mut self) -> Result { - // listen(self) - // } - - // pub fn event_listen_raw(&mut self) -> String { - // listen_raw(self) - // } - - pub async fn next(&self) -> Result<(), Error> { - self.run_command(MpvCommand::PlaylistNext).await - } - - pub async fn observe_property(&self, id: isize, property: &str) -> Result<(), Error> { - self.run_command(MpvCommand::Observe { - id, - property: property.to_string(), - }) - .await - } - - pub async fn unobserve_property(&self, id: isize) -> Result<(), Error> { - self.run_command(MpvCommand::Unobserve(id)).await - } - - pub async fn pause(&self) -> Result<(), Error> { - self.set_property("pause", true).await - } - - pub async fn prev(&self) -> Result<(), Error> { - self.run_command(MpvCommand::PlaylistPrev).await - } - - pub async fn restart(&self) -> Result<(), Error> { - self.run_command(MpvCommand::Seek { - seconds: 0f64, - option: SeekOptions::Absolute, - }) - .await - } - /// # Description /// /// Runs mpv commands. The arguments are passed as a String-Vector reference: @@ -760,120 +669,6 @@ impl Mpv { self.run_command_raw(command, args).await.map(|_| ()) } - pub async fn playlist_add( - &self, - file: &str, - file_type: PlaylistAddTypeOptions, - option: PlaylistAddOptions, - ) -> Result<(), Error> { - match file_type { - PlaylistAddTypeOptions::File => { - self.run_command(MpvCommand::LoadFile { - file: file.to_string(), - option, - }) - .await - } - - PlaylistAddTypeOptions::Playlist => { - self.run_command(MpvCommand::LoadList { - file: file.to_string(), - option, - }) - .await - } - } - } - - pub async fn playlist_clear(&self) -> Result<(), Error> { - self.run_command(MpvCommand::PlaylistClear).await - } - - pub async fn playlist_move_id(&self, from: usize, to: usize) -> Result<(), Error> { - self.run_command(MpvCommand::PlaylistMove { from, to }) - .await - } - - pub async fn playlist_play_id(&self, id: usize) -> Result<(), Error> { - self.set_property("playlist-pos", id).await - } - - pub async fn playlist_play_next(&self, id: usize) -> Result<(), Error> { - match self.get_property::("playlist-pos").await { - Ok(current_id) => { - self.run_command(MpvCommand::PlaylistMove { - from: id, - to: current_id + 1, - }) - .await - } - Err(msg) => Err(msg), - } - } - - pub async fn playlist_remove_id(&self, id: usize) -> Result<(), Error> { - self.run_command(MpvCommand::PlaylistRemove(id)).await - } - - pub async fn playlist_shuffle(&self) -> Result<(), Error> { - self.run_command(MpvCommand::PlaylistShuffle).await - } - - pub async fn seek(&self, seconds: f64, option: SeekOptions) -> Result<(), Error> { - self.run_command(MpvCommand::Seek { seconds, option }).await - } - - pub async fn set_loop_file(&self, option: Switch) -> Result<(), Error> { - let enabled = match option { - Switch::On => "inf", - Switch::Off => "no", - Switch::Toggle => { - self.get_property::("loop-file") - .await - .map(|s| match s.as_str() { - "inf" => "no", - "no" => "inf", - _ => "no", - })? - } - }; - self.set_property("loop-file", enabled).await - } - - pub async fn set_loop_playlist(&self, option: Switch) -> Result<(), Error> { - let enabled = match option { - Switch::On => "inf", - Switch::Off => "no", - Switch::Toggle => { - self.get_property::("loop-playlist") - .await - .map(|s| match s.as_str() { - "inf" => "no", - "no" => "inf", - _ => "no", - })? - } - }; - self.set_property("loo-playlist", enabled).await - } - - pub async fn set_mute(&self, option: Switch) -> Result<(), Error> { - let enabled = match option { - Switch::On => "yes", - Switch::Off => "no", - Switch::Toggle => { - self.get_property::("mute") - .await - .map(|s| match s.as_str() { - "yes" => "no", - "no" => "yes", - _ => "no", - })? - } - }; - self.set_property("mute", enabled).await - } - /// # Description /// /// Sets the mpv property __ to __. @@ -905,54 +700,4 @@ impl Mpv { ) -> Result<(), Error> { T::set_property_generic(self, property, value).await } - - pub async fn set_speed( - &self, - input_speed: f64, - option: NumberChangeOptions, - ) -> Result<(), Error> { - match self.get_property::("speed").await { - Ok(speed) => match option { - NumberChangeOptions::Increase => { - self.set_property("speed", speed + input_speed).await - } - - NumberChangeOptions::Decrease => { - self.set_property("speed", speed - input_speed).await - } - - NumberChangeOptions::Absolute => self.set_property("speed", input_speed).await, - }, - Err(msg) => Err(msg), - } - } - - pub async fn set_volume( - &self, - input_volume: f64, - option: NumberChangeOptions, - ) -> Result<(), Error> { - match self.get_property::("volume").await { - Ok(volume) => match option { - NumberChangeOptions::Increase => { - self.set_property("volume", volume + input_volume).await - } - - NumberChangeOptions::Decrease => { - self.set_property("volume", volume - input_volume).await - } - - NumberChangeOptions::Absolute => self.set_property("volume", input_volume).await, - }, - Err(msg) => Err(msg), - } - } - - pub async fn stop(&self) -> Result<(), Error> { - self.run_command(MpvCommand::Stop).await - } - - pub async fn toggle(&self) -> Result<(), Error> { - self.run_command_raw("cycle", &["pause"]).await.map(|_| ()) - } } diff --git a/src/api_extension.rs b/src/api_extension.rs new file mode 100644 index 0000000..608b1b0 --- /dev/null +++ b/src/api_extension.rs @@ -0,0 +1,269 @@ +use crate::{Error, IntoRawCommandPart, Mpv, MpvCommand, MpvDataType, Playlist, PlaylistAddOptions, PlaylistAddTypeOptions, PlaylistEntry, SeekOptions}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum NumberChangeOptions { + Absolute, + Increase, + Decrease, +} + +impl IntoRawCommandPart for NumberChangeOptions { + fn into_raw_command_part(self) -> String { + match self { + NumberChangeOptions::Absolute => "absolute".to_string(), + NumberChangeOptions::Increase => "increase".to_string(), + NumberChangeOptions::Decrease => "decrease".to_string(), + } + } +} + +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +pub enum Switch { + On, + Off, + Toggle, +} + +// TODO: fix this +#[allow(async_fn_in_trait)] +pub trait MpvExt { + async fn toggle(&self) -> Result<(), Error>; + async fn stop(&self) -> Result<(), Error>; + async fn set_volume(&self, input_volume: f64, option: NumberChangeOptions) -> Result<(), Error>; + async fn set_speed(&self, input_speed: f64, option: NumberChangeOptions) -> Result<(), Error>; + async fn set_mute(&self, option: Switch) -> Result<(), Error>; + async fn set_loop_playlist(&self, option: Switch) -> Result<(), Error>; + async fn set_loop_file(&self, option: Switch) -> Result<(), Error>; + async fn seek(&self, seconds: f64, option: SeekOptions) -> Result<(), Error>; + async fn playlist_shuffle(&self) -> Result<(), Error>; + async fn playlist_remove_id(&self, id: usize) -> Result<(), Error>; + async fn playlist_play_next(&self, id: usize) -> Result<(), Error>; + async fn playlist_play_id(&self, id: usize) -> Result<(), Error>; + async fn playlist_move_id(&self, from: usize, to: usize) -> Result<(), Error>; + async fn playlist_clear(&self) -> Result<(), Error>; + async fn playlist_add(&self, file: &str, file_type: PlaylistAddTypeOptions, option: PlaylistAddOptions) -> Result<(), Error>; + async fn restart(&self) -> Result<(), Error>; + async fn prev(&self) -> Result<(), Error>; + async fn pause(&self) -> Result<(), Error>; + async fn unobserve_property(&self, id: isize) -> Result<(), Error>; + async fn observe_property(&self, id: isize, property: &str) -> Result<(), Error>; + async fn next(&self) -> Result<(), Error>; + async fn kill(&self) -> Result<(), Error>; + async fn get_playlist(&self) -> Result; + async fn get_metadata(&self) -> Result, Error>; + +} + +impl MpvExt for Mpv { + async fn get_metadata(&self) -> Result, Error> { + self.get_property("metadata").await + } + + async fn get_playlist(&self) -> Result { + self.get_property::>("playlist") + .await + .map(|entries| Playlist(entries)) + } + + async fn kill(&self) -> Result<(), Error> { + self.run_command(MpvCommand::Quit).await + } + + async fn next(&self) -> Result<(), Error> { + self.run_command(MpvCommand::PlaylistNext).await + } + + async fn observe_property(&self, id: isize, property: &str) -> Result<(), Error> { + self.run_command(MpvCommand::Observe { + id, + property: property.to_string(), + }) + .await + } + + async fn unobserve_property(&self, id: isize) -> Result<(), Error> { + self.run_command(MpvCommand::Unobserve(id)).await + } + + async fn pause(&self) -> Result<(), Error> { + self.set_property("pause", true).await + } + + async fn prev(&self) -> Result<(), Error> { + self.run_command(MpvCommand::PlaylistPrev).await + } + + async fn restart(&self) -> Result<(), Error> { + self.run_command(MpvCommand::Seek { + seconds: 0f64, + option: SeekOptions::Absolute, + }) + .await + } + + async fn playlist_add( + &self, + file: &str, + file_type: PlaylistAddTypeOptions, + option: PlaylistAddOptions, + ) -> Result<(), Error> { + match file_type { + PlaylistAddTypeOptions::File => { + self.run_command(MpvCommand::LoadFile { + file: file.to_string(), + option, + }) + .await + } + + PlaylistAddTypeOptions::Playlist => { + self.run_command(MpvCommand::LoadList { + file: file.to_string(), + option, + }) + .await + } + } + } + + async fn playlist_clear(&self) -> Result<(), Error> { + self.run_command(MpvCommand::PlaylistClear).await + } + + async fn playlist_move_id(&self, from: usize, to: usize) -> Result<(), Error> { + self.run_command(MpvCommand::PlaylistMove { from, to }) + .await + } + + async fn playlist_play_id(&self, id: usize) -> Result<(), Error> { + self.set_property("playlist-pos", id).await + } + + async fn playlist_play_next(&self, id: usize) -> Result<(), Error> { + match self.get_property::("playlist-pos").await { + Ok(current_id) => { + self.run_command(MpvCommand::PlaylistMove { + from: id, + to: current_id + 1, + }) + .await + } + Err(msg) => Err(msg), + } + } + + async fn playlist_remove_id(&self, id: usize) -> Result<(), Error> { + self.run_command(MpvCommand::PlaylistRemove(id)).await + } + + async fn playlist_shuffle(&self) -> Result<(), Error> { + self.run_command(MpvCommand::PlaylistShuffle).await + } + + async fn seek(&self, seconds: f64, option: SeekOptions) -> Result<(), Error> { + self.run_command(MpvCommand::Seek { seconds, option }).await + } + + async fn set_loop_file(&self, option: Switch) -> Result<(), Error> { + let enabled = match option { + Switch::On => "inf", + Switch::Off => "no", + Switch::Toggle => { + self.get_property::("loop-file") + .await + .map(|s| match s.as_str() { + "inf" => "no", + "no" => "inf", + _ => "no", + })? + } + }; + self.set_property("loop-file", enabled).await + } + + async fn set_loop_playlist(&self, option: Switch) -> Result<(), Error> { + let enabled = match option { + Switch::On => "inf", + Switch::Off => "no", + Switch::Toggle => { + self.get_property::("loop-playlist") + .await + .map(|s| match s.as_str() { + "inf" => "no", + "no" => "inf", + _ => "no", + })? + } + }; + self.set_property("loo-playlist", enabled).await + } + + async fn set_mute(&self, option: Switch) -> Result<(), Error> { + let enabled = match option { + Switch::On => "yes", + Switch::Off => "no", + Switch::Toggle => { + self.get_property::("mute") + .await + .map(|s| match s.as_str() { + "yes" => "no", + "no" => "yes", + _ => "no", + })? + } + }; + self.set_property("mute", enabled).await + } + + async fn set_speed( + &self, + input_speed: f64, + option: NumberChangeOptions, + ) -> Result<(), Error> { + match self.get_property::("speed").await { + Ok(speed) => match option { + NumberChangeOptions::Increase => { + self.set_property("speed", speed + input_speed).await + } + + NumberChangeOptions::Decrease => { + self.set_property("speed", speed - input_speed).await + } + + NumberChangeOptions::Absolute => self.set_property("speed", input_speed).await, + }, + Err(msg) => Err(msg), + } + } + + async fn set_volume( + &self, + input_volume: f64, + option: NumberChangeOptions, + ) -> Result<(), Error> { + match self.get_property::("volume").await { + Ok(volume) => match option { + NumberChangeOptions::Increase => { + self.set_property("volume", volume + input_volume).await + } + + NumberChangeOptions::Decrease => { + self.set_property("volume", volume - input_volume).await + } + + NumberChangeOptions::Absolute => self.set_property("volume", input_volume).await, + }, + Err(msg) => Err(msg), + } + } + + async fn stop(&self) -> Result<(), Error> { + self.run_command(MpvCommand::Stop).await + } + + async fn toggle(&self) -> Result<(), Error> { + self.run_command_raw("cycle", &["pause"]).await.map(|_| ()) + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 385fa19..7ff6196 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,7 @@ mod api; mod ipc; mod message_parser; +mod api_extension; pub use api::*; +pub use api_extension::*; \ No newline at end of file diff --git a/tests/events.rs b/tests/events.rs index de0733f..a5584ef 100644 --- a/tests/events.rs +++ b/tests/events.rs @@ -1,7 +1,7 @@ use std::panic; use futures::{stream::StreamExt, SinkExt}; -use mpvipc::{Mpv, MpvDataType, Property}; +use mpvipc::{Mpv, MpvExt, MpvDataType, Property}; use serde_json::json; use test_log::test; use tokio::{net::UnixStream, task::JoinHandle}; diff --git a/tests/get_property.rs b/tests/get_property.rs index 55cef43..cb7367e 100644 --- a/tests/get_property.rs +++ b/tests/get_property.rs @@ -1,7 +1,7 @@ use std::{panic, time::Duration}; use futures::{stream::FuturesUnordered, SinkExt, StreamExt}; -use mpvipc::{Error, ErrorCode, Mpv, Playlist, PlaylistEntry}; +use mpvipc::{Error, ErrorCode, Mpv, MpvExt, Playlist, PlaylistEntry}; use serde_json::{json, Value}; use test_log::test; use tokio::{net::UnixStream, task::JoinHandle}; diff --git a/tests/set_property.rs b/tests/set_property.rs index 3c4275f..a91a231 100644 --- a/tests/set_property.rs +++ b/tests/set_property.rs @@ -1,7 +1,7 @@ use std::{panic, time::Duration}; use futures::{stream::FuturesUnordered, SinkExt, StreamExt}; -use mpvipc::{Error, ErrorCode, Mpv, Playlist, PlaylistEntry}; +use mpvipc::{Error, ErrorCode, Mpv, MpvExt, Playlist, PlaylistEntry}; use serde_json::{json, Value}; use test_log::test; use tokio::{net::UnixStream, task::JoinHandle};