diff options
Diffstat (limited to '')
-rw-r--r-- | crates/libmpv2/src/mpv.rs | 69 |
1 files changed, 32 insertions, 37 deletions
diff --git a/crates/libmpv2/src/mpv.rs b/crates/libmpv2/src/mpv.rs index 07d0976..d8164c0 100644 --- a/crates/libmpv2/src/mpv.rs +++ b/crates/libmpv2/src/mpv.rs @@ -184,7 +184,7 @@ pub mod mpv_node { pub mod sys_node { use super::{DropWrapper, MpvNode, MpvNodeArrayIter, MpvNodeMapIter}; - use crate::{mpv_error, mpv_format, Error, Result}; + use crate::{Error, Result, mpv_error, mpv_format}; use std::rc::Rc; #[derive(Debug, Clone)] @@ -375,14 +375,14 @@ unsafe impl SetData for String { /// Wrapper around an `&str` returned by mpv, that properly deallocates it with mpv's allocator. #[derive(Debug, Hash, Eq, PartialEq)] pub struct MpvStr<'a>(&'a str); -impl<'a> Deref for MpvStr<'a> { +impl Deref for MpvStr<'_> { type Target = str; fn deref(&self) -> &str { self.0 } } -impl<'a> Drop for MpvStr<'a> { +impl Drop for MpvStr<'_> { fn drop(&mut self) { unsafe { libmpv2_sys::mpv_free(self.0.as_ptr() as *mut u8 as _) }; } @@ -403,7 +403,7 @@ unsafe impl<'a> GetData for MpvStr<'a> { } } -unsafe impl<'a> SetData for &'a str { +unsafe impl SetData for &str { fn call_as_c_void<T, F: FnMut(*mut ctype::c_void) -> Result<T>>(self, mut fun: F) -> Result<T> { let string = CString::new(self)?; fun((&mut string.as_ptr()) as *mut *const ctype::c_char as *mut _) @@ -511,9 +511,8 @@ impl Mpv { } initializer(MpvInitializer { ctx })?; - mpv_err((), unsafe { libmpv2_sys::mpv_initialize(ctx) }).map_err(|err| { + mpv_err((), unsafe { libmpv2_sys::mpv_initialize(ctx) }).inspect_err(|_| { unsafe { libmpv2_sys::mpv_terminate_destroy(ctx) }; - err })?; let ctx = unsafe { NonNull::new_unchecked(ctx) }; @@ -526,19 +525,6 @@ impl Mpv { }) } - /// Execute a command - pub fn execute(&self, name: &str, args: &[&str]) -> Result<()> { - if args.is_empty() { - debug!("Running mpv command: '{}'", name); - } else { - debug!("Running mpv command: '{} {}'", name, args.join(" ")); - } - - self.command(name, args)?; - - Ok(()) - } - /// Load a configuration file. The path has to be absolute, and a file. pub fn load_config(&self, path: &str) -> Result<()> { let file = CString::new(path)?.into_raw(); @@ -562,33 +548,40 @@ impl Mpv { /// Send a command to the `Mpv` instance. This uses `mpv_command_string` internally, /// so that the syntax is the same as described in the [manual for the input.conf](https://mpv.io/manual/master/#list-of-input-commands). /// - /// Note that you may have to escape strings with `""` when they contain spaces. + /// Note that this function escapes the arguments for you. /// /// # Examples /// - /// ```dont_run - /// # use libmpv2::{Mpv}; - /// # use libmpv2::mpv_node::MpvNode; - /// # use libmpv2::mpv::errors::Result; - /// # use std::collections::HashMap; - /// # - /// # fn main() -> Result<()> { - /// # let mpv = Mpv::new()?; + /// ```text + ///# use libmpv2::{Mpv}; + ///# use libmpv2::mpv_node::MpvNode; + ///# use libmpv2::mpv::errors::Result; + ///# use std::collections::HashMap; + ///# + ///# fn main() -> Result<()> { + ///# let mpv = Mpv::new()?; /// mpv.command("loadfile", &["test-data/jellyfish.mp4", "append-play"]).unwrap(); - /// # let node = mpv.get_property::<MpvNode>("playlist").unwrap(); - /// # let mut list = node.array().unwrap().collect::<Vec<_>>(); - /// # let map = list.pop().unwrap().map().unwrap().collect::<HashMap<_, _>>(); - /// # assert_eq!(map, HashMap::from([(String::from("id"), MpvNode::Int64(1)), (String::from("current"), MpvNode::Flag(true)), (String::from("filename"), MpvNode::String(String::from("test-data/jellyfish.mp4")))])); - /// # Ok(()) - /// # } + ///# let node = mpv.get_property::<MpvNode>("playlist").unwrap(); + ///# let mut list = node.array().unwrap().collect::<Vec<_>>(); + ///# let map = list.pop().unwrap().map().unwrap().collect::<HashMap<_, _>>(); + ///# assert_eq!(map, HashMap::from([(String::from("id"), MpvNode::Int64(1)), (String::from("current"), MpvNode::Flag(true)), (String::from("filename"), MpvNode::String(String::from("test-data/jellyfish.mp4")))])); + ///# Ok(()) + ///# } /// ``` pub fn command(&self, name: &str, args: &[&str]) -> Result<()> { - let mut cmd = name.to_owned(); + fn escape(input: &str) -> String { + input.replace('"', "\\\"") + } + + let mut cmd = escape(name); for elem in args { cmd.push(' '); - cmd.push_str(elem); + cmd.push('"'); + cmd.push_str(&escape(elem)); + cmd.push('"'); } + debug!("Running mpv command: '{}'", cmd); let raw = CString::new(cmd)?; mpv_err((), unsafe { @@ -597,7 +590,9 @@ impl Mpv { } /// Set the value of a property. - pub fn set_property<T: SetData>(&self, name: &str, data: T) -> Result<()> { + pub fn set_property<T: SetData + std::fmt::Display>(&self, name: &str, data: T) -> Result<()> { + debug!("Setting mpv property: '{name}' = '{data}'"); + let name = CString::new(name)?; let format = T::get_format().as_mpv_format() as _; data.call_as_c_void(|ptr| { |