go less wild with generic traits

This commit is contained in:
Erica Z 2024-11-03 10:16:25 +01:00
parent 8699f7bf4f
commit d3a37dec1b
3 changed files with 29 additions and 66 deletions

View file

@ -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;

View file

@ -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<T>(self, f: impl FnOnce(ffi::mpv_format, *mut c_void) -> T) -> T;
fn from_data<T>(
format: ffi::mpv_format,
data: *mut c_void,
f: impl FnOnce(Option<Self>) -> 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<T>(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<T>(
_format: ffi::mpv_format,
_data: *mut c_void,
_f: impl FnOnce(Option<Self>) -> 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<T>(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<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!(),
}
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::<c_int>(&value) as *mut c_void,
)
}
}

View file

@ -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<Item = &'a str>) -> Result<(), Error> {