mpv_client_dyn/
format.rs

1use super::ffi::mpv_free;
2use super::Result;
3
4use std::ffi::{c_char, c_int, c_void, CStr, CString};
5
6pub trait Format: Sized + Default {
7    const MPV_FORMAT: i32;
8    fn from_ptr(ptr: *const c_void) -> Result<Self>;
9    fn to_mpv<F: Fn(*const c_void) -> Result<()>>(self, fun: F) -> Result<()>;
10    fn from_mpv<F: Fn(*mut c_void) -> Result<()>>(fun: F) -> Result<Self>;
11}
12
13impl Format for String {
14    const MPV_FORMAT: i32 = 1;
15
16    fn from_ptr(ptr: *const c_void) -> Result<Self> {
17        let ptr = ptr as *const *const c_char;
18        Ok(unsafe { CStr::from_ptr(*ptr) }.to_str()?.to_string())
19    }
20
21    fn to_mpv<F: Fn(*const c_void) -> Result<()>>(self, fun: F) -> Result<()> {
22        let str = CString::new::<String>(self.into())?;
23        fun(&str.as_ptr() as *const *const c_char as *const c_void)
24    }
25
26    fn from_mpv<F: Fn(*mut c_void) -> Result<()>>(fun: F) -> Result<Self> {
27        let mut ptr: *mut c_char = std::ptr::null_mut();
28        fun(&mut ptr as *mut _ as *mut c_void).and_then(|()| unsafe {
29            let str = CStr::from_ptr(ptr);
30            let str = str.to_str().map(|s| s.to_owned());
31            mpv_free(ptr as *mut c_void);
32            Ok(str?)
33        })
34    }
35}
36
37impl Format for bool {
38    const MPV_FORMAT: i32 = 3;
39
40    fn from_ptr(ptr: *const c_void) -> Result<Self> {
41        Ok(unsafe { *(ptr as *const c_int) != 0 })
42    }
43
44    fn to_mpv<F: Fn(*const c_void) -> Result<()>>(self, fun: F) -> Result<()> {
45        let data = self as c_int;
46        fun(&data as *const _ as *const c_void)
47    }
48
49    fn from_mpv<F: Fn(*mut c_void) -> Result<()>>(fun: F) -> Result<Self> {
50        let mut data = Self::default() as c_int;
51        fun(&mut data as *mut _ as *mut c_void).map(|()| data != 0)
52    }
53}
54
55impl Format for i64 {
56    const MPV_FORMAT: i32 = 4;
57
58    fn from_ptr(ptr: *const c_void) -> Result<Self> {
59        Ok(unsafe { *(ptr as *const Self) })
60    }
61
62    fn to_mpv<F: Fn(*const c_void) -> Result<()>>(self, fun: F) -> Result<()> {
63        fun(&self as *const _ as *const c_void)
64    }
65
66    fn from_mpv<F: Fn(*mut c_void) -> Result<()>>(fun: F) -> Result<Self> {
67        let mut data = Self::default();
68        fun(&mut data as *mut _ as *mut c_void).map(|()| data)
69    }
70}
71
72impl Format for f64 {
73    const MPV_FORMAT: i32 = 5;
74
75    fn from_ptr(ptr: *const c_void) -> Result<Self> {
76        Ok(unsafe { *(ptr as *const Self) })
77    }
78
79    fn to_mpv<F: Fn(*const c_void) -> Result<()>>(self, fun: F) -> Result<()> {
80        fun(&self as *const _ as *const c_void)
81    }
82
83    fn from_mpv<F: Fn(*mut c_void) -> Result<()>>(fun: F) -> Result<Self> {
84        let mut data = Self::default();
85        fun(&mut data as *mut _ as *mut c_void).map(|()| data)
86    }
87}