go less wild with generic traits
This commit is contained in:
parent
8699f7bf4f
commit
d3a37dec1b
3 changed files with 29 additions and 66 deletions
|
@ -4,7 +4,7 @@ mod error;
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
|
|
||||||
mod format;
|
mod format;
|
||||||
pub use format::FormatValue;
|
pub use format::SetProperty;
|
||||||
|
|
||||||
mod handle;
|
mod handle;
|
||||||
pub use handle::Handle;
|
pub use handle::Handle;
|
||||||
|
|
|
@ -1,67 +1,34 @@
|
||||||
use super::ffi;
|
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 {
|
pub trait SetProperty {
|
||||||
const FORMAT: ffi::mpv_format;
|
/// # Safety
|
||||||
fn into_data<T>(self, f: impl FnOnce(ffi::mpv_format, *mut c_void) -> T) -> T;
|
/// see mpv_set_property
|
||||||
fn from_data<T>(
|
unsafe fn set_property(self, ctx: *mut ffi::mpv_handle, name: *const c_char) -> c_int;
|
||||||
format: ffi::mpv_format,
|
|
||||||
data: *mut c_void,
|
|
||||||
f: impl FnOnce(Option<Self>) -> T,
|
|
||||||
) -> T;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FormatValue for &'a str {
|
impl<'a> SetProperty for &'a str {
|
||||||
const FORMAT: ffi::mpv_format = ffi::mpv_format_MPV_FORMAT_STRING;
|
unsafe fn set_property(self, ctx: *mut ffi::mpv_handle, name: *const c_char) -> c_int {
|
||||||
|
// need to add zero terminator
|
||||||
fn into_data<T>(self, f: impl FnOnce(ffi::mpv_format, *mut c_void) -> T) -> T {
|
let value = CString::new(self).expect("null bytes in string property value");
|
||||||
let str = CString::new(self).expect("null bytes in string");
|
let value_ptr: *const c_char = value.as_ptr();
|
||||||
let str_ptr = str.as_ptr();
|
ffi::mpv_set_property(
|
||||||
f(Self::FORMAT, (&str_ptr) as *const _ as *mut c_void)
|
ctx,
|
||||||
}
|
name,
|
||||||
|
ffi::mpv_format_MPV_FORMAT_STRING,
|
||||||
fn from_data<T>(
|
std::ptr::from_ref::<*const c_char>(&value_ptr) as *mut c_void,
|
||||||
_format: ffi::mpv_format,
|
)
|
||||||
_data: *mut c_void,
|
|
||||||
_f: impl FnOnce(Option<Self>) -> T,
|
|
||||||
) -> T {
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormatValue for bool {
|
impl SetProperty for bool {
|
||||||
const FORMAT: ffi::mpv_format = ffi::mpv_format_MPV_FORMAT_FLAG;
|
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 };
|
||||||
fn into_data<T>(self, f: impl FnOnce(ffi::mpv_format, *mut c_void) -> T) -> T {
|
ffi::mpv_set_property(
|
||||||
let flag: c_int = if self { 1 } else { 0 };
|
ctx,
|
||||||
f(Self::FORMAT, (&flag) as *const c_int as *mut c_void)
|
name,
|
||||||
}
|
ffi::mpv_format_MPV_FORMAT_FLAG,
|
||||||
|
std::ptr::from_ref::<c_int>(&value) as *mut c_void,
|
||||||
fn from_data<T>(
|
)
|
||||||
_format: ffi::mpv_format,
|
|
||||||
_data: *mut c_void,
|
|
||||||
_f: impl FnOnce(Option<Self>) -> T,
|
|
||||||
) -> T {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FormatValue for f64 {
|
|
||||||
const FORMAT: ffi::mpv_format = ffi::mpv_format_MPV_FORMAT_DOUBLE;
|
|
||||||
|
|
||||||
fn into_data<T>(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<T>(
|
|
||||||
format: ffi::mpv_format,
|
|
||||||
data: *mut c_void,
|
|
||||||
f: impl FnOnce(Option<Self>) -> 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!(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{ffi, Error, FormatValue};
|
use super::{ffi, Error, SetProperty};
|
||||||
use event_listener::{Event, EventListener, IntoNotification};
|
use event_listener::{Event, EventListener, IntoNotification};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ffi::{c_char, c_void, CStr, CString};
|
use std::ffi::{c_char, c_void, CStr, CString};
|
||||||
|
@ -77,14 +77,10 @@ impl Handle {
|
||||||
unsafe { ffi::mpv_client_id(self.inner.as_ptr()) }
|
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
|
// need to add zero terminator
|
||||||
let name = CString::new(name).expect("null bytes in property name");
|
let name = CString::new(name).expect("null bytes in property name");
|
||||||
value.into_data(|format, data| {
|
Error::from_return_code(unsafe { value.set_property(self.inner.as_ptr(), name.as_ptr()) })
|
||||||
Error::from_return_code(unsafe {
|
|
||||||
ffi::mpv_set_property(self.inner.as_ptr(), name.as_ptr(), format, data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn command<'a>(&self, args: impl IntoIterator<Item = &'a str>) -> Result<(), Error> {
|
pub fn command<'a>(&self, args: impl IntoIterator<Item = &'a str>) -> Result<(), Error> {
|
||||||
|
|
Loading…
Reference in a new issue