diff --git a/src/mpv.rs b/src/mpv.rs index 6a190d4..381be2f 100644 --- a/src/mpv.rs +++ b/src/mpv.rs @@ -4,7 +4,7 @@ mod error; pub use error::Error; mod format; -pub use format::FormatValue; +pub use format::SetProperty; mod handle; pub use handle::Handle; diff --git a/src/mpv/format.rs b/src/mpv/format.rs index a7bbbf0..d56dd27 100644 --- a/src/mpv/format.rs +++ b/src/mpv/format.rs @@ -1,67 +1,34 @@ use super::ffi; -use std::ffi::{c_int, c_void, CString}; +use std::ffi::{c_char, c_int, c_void, CString}; -pub trait FormatValue: Sized { - const FORMAT: ffi::mpv_format; - fn into_data(self, f: impl FnOnce(ffi::mpv_format, *mut c_void) -> T) -> T; - fn from_data( - format: ffi::mpv_format, - data: *mut c_void, - f: impl FnOnce(Option) -> T, - ) -> T; +pub trait SetProperty { + /// # Safety + /// see mpv_set_property + unsafe fn set_property(self, ctx: *mut ffi::mpv_handle, name: *const c_char) -> c_int; } -impl<'a> FormatValue for &'a str { - const FORMAT: ffi::mpv_format = ffi::mpv_format_MPV_FORMAT_STRING; - - fn into_data(self, f: impl FnOnce(ffi::mpv_format, *mut c_void) -> T) -> T { - let str = CString::new(self).expect("null bytes in string"); - let str_ptr = str.as_ptr(); - f(Self::FORMAT, (&str_ptr) as *const _ as *mut c_void) - } - - fn from_data( - _format: ffi::mpv_format, - _data: *mut c_void, - _f: impl FnOnce(Option) -> T, - ) -> T { - todo!() +impl<'a> SetProperty for &'a str { + unsafe fn set_property(self, ctx: *mut ffi::mpv_handle, name: *const c_char) -> c_int { + // need to add zero terminator + let value = CString::new(self).expect("null bytes in string property value"); + let value_ptr: *const c_char = value.as_ptr(); + ffi::mpv_set_property( + ctx, + name, + ffi::mpv_format_MPV_FORMAT_STRING, + std::ptr::from_ref::<*const c_char>(&value_ptr) as *mut c_void, + ) } } -impl FormatValue for bool { - const FORMAT: ffi::mpv_format = ffi::mpv_format_MPV_FORMAT_FLAG; - - fn into_data(self, f: impl FnOnce(ffi::mpv_format, *mut c_void) -> T) -> T { - let flag: c_int = if self { 1 } else { 0 }; - f(Self::FORMAT, (&flag) as *const c_int as *mut c_void) - } - - fn from_data( - _format: ffi::mpv_format, - _data: *mut c_void, - _f: impl FnOnce(Option) -> T, - ) -> T { - todo!() - } -} - -impl FormatValue for f64 { - const FORMAT: ffi::mpv_format = ffi::mpv_format_MPV_FORMAT_DOUBLE; - - fn into_data(self, f: impl FnOnce(ffi::mpv_format, *mut c_void) -> T) -> T { - f(Self::FORMAT, (&self) as *const f64 as *mut c_void) - } - - fn from_data( - format: ffi::mpv_format, - data: *mut c_void, - f: impl FnOnce(Option) -> T, - ) -> T { - match format { - ffi::mpv_format_MPV_FORMAT_NONE => f(None), - ffi::mpv_format_MPV_FORMAT_DOUBLE => f(Some(unsafe { *(data as *mut f64) })), - _ => panic!(), - } +impl SetProperty for bool { + unsafe fn set_property(self, ctx: *mut ffi::mpv_handle, name: *const c_char) -> c_int { + let value: c_int = if self { 1 } else { 0 }; + ffi::mpv_set_property( + ctx, + name, + ffi::mpv_format_MPV_FORMAT_FLAG, + std::ptr::from_ref::(&value) as *mut c_void, + ) } } diff --git a/src/mpv/handle.rs b/src/mpv/handle.rs index 341ca6b..d28fbfb 100644 --- a/src/mpv/handle.rs +++ b/src/mpv/handle.rs @@ -1,4 +1,4 @@ -use super::{ffi, Error, FormatValue}; +use super::{ffi, Error, SetProperty}; use event_listener::{Event, EventListener, IntoNotification}; use std::cell::RefCell; use std::ffi::{c_char, c_void, CStr, CString}; @@ -77,14 +77,10 @@ impl Handle { unsafe { ffi::mpv_client_id(self.inner.as_ptr()) } } - pub fn set_property(&self, name: &str, value: impl FormatValue) -> Result<(), Error> { + pub fn set_property(&self, name: &str, value: impl SetProperty) -> Result<(), Error> { // need to add zero terminator let name = CString::new(name).expect("null bytes in property name"); - value.into_data(|format, data| { - Error::from_return_code(unsafe { - ffi::mpv_set_property(self.inner.as_ptr(), name.as_ptr(), format, data) - }) - }) + Error::from_return_code(unsafe { value.set_property(self.inner.as_ptr(), name.as_ptr()) }) } pub fn command<'a>(&self, args: impl IntoIterator) -> Result<(), Error> {