Skip to main content

mpv_client_cross/
format.rs

1use super::Result;
2use super::{mpv_format_MPV_FORMAT_NONE, mpv_free, mpv_free_node_contents, mpv_node, mpv_node__bindgen_ty_1};
3
4use std::ffi::{c_char, c_int, c_void, CStr, CString};
5
6use super::node::{from_mpv_node, to_mpv_node, Node};
7
8pub trait Format: Sized + Default {
9    const MPV_FORMAT: u32;
10    fn from_ptr(ptr: *const c_void) -> Result<Self>;
11    fn to_mpv<F: Fn(*mut c_void) -> Result<()>>(self, fun: F) -> Result<()>;
12    fn from_mpv<F: Fn(*mut c_void) -> Result<()>>(fun: F) -> Result<Self>;
13}
14
15impl Format for String {
16    const MPV_FORMAT: u32 = 1;
17
18    fn from_ptr(ptr: *const c_void) -> Result<Self> {
19        let ptr = ptr as *const *const c_char;
20        Ok(unsafe { CStr::from_ptr(*ptr) }.to_str()?.to_string())
21    }
22
23    fn to_mpv<F: Fn(*mut c_void) -> Result<()>>(self, fun: F) -> Result<()> {
24        let str = CString::new::<String>(self)?;
25        fun(&str.as_ptr() as *const *const c_char as *mut c_void)
26    }
27
28    fn from_mpv<F: Fn(*mut c_void) -> Result<()>>(fun: F) -> Result<Self> {
29        let mut ptr: *mut c_char = std::ptr::null_mut();
30        fun(&mut ptr as *mut _ as *mut c_void).and_then(|()| unsafe {
31            let str = CStr::from_ptr(ptr);
32            let str = str.to_str().map(|s| s.to_owned());
33            mpv_free(ptr as *mut c_void);
34            Ok(str?)
35        })
36    }
37}
38
39impl Format for bool {
40    const MPV_FORMAT: u32 = 3;
41
42    fn from_ptr(ptr: *const c_void) -> Result<Self> {
43        Ok(unsafe { *(ptr as *const c_int) != 0 })
44    }
45
46    fn to_mpv<F: Fn(*mut c_void) -> Result<()>>(self, fun: F) -> Result<()> {
47        let data = self as c_int;
48        fun(&data as *const _ as *mut c_void)
49    }
50
51    fn from_mpv<F: Fn(*mut c_void) -> Result<()>>(fun: F) -> Result<Self> {
52        let mut data = Self::default() as c_int;
53        fun(&mut data as *mut _ as *mut c_void).map(|()| data != 0)
54    }
55}
56
57impl Format for i64 {
58    const MPV_FORMAT: u32 = 4;
59
60    fn from_ptr(ptr: *const c_void) -> Result<Self> {
61        Ok(unsafe { *(ptr as *const Self) })
62    }
63
64    fn to_mpv<F: Fn(*mut c_void) -> Result<()>>(self, fun: F) -> Result<()> {
65        fun(&self as *const _ as *mut c_void)
66    }
67
68    fn from_mpv<F: Fn(*mut c_void) -> Result<()>>(fun: F) -> Result<Self> {
69        let mut data = Self::default();
70        fun(&mut data as *mut _ as *mut c_void).map(|()| data)
71    }
72}
73
74impl Format for f64 {
75    const MPV_FORMAT: u32 = 5;
76
77    fn from_ptr(ptr: *const c_void) -> Result<Self> {
78        Ok(unsafe { *(ptr as *const Self) })
79    }
80
81    fn to_mpv<F: Fn(*mut c_void) -> Result<()>>(self, fun: F) -> Result<()> {
82        fun(&self as *const _ as *mut c_void)
83    }
84
85    fn from_mpv<F: Fn(*mut c_void) -> Result<()>>(fun: F) -> Result<Self> {
86        let mut data = Self::default();
87        fun(&mut data as *mut _ as *mut c_void).map(|()| data)
88    }
89}
90
91impl Format for Node {
92    const MPV_FORMAT: u32 = 6;
93
94    fn from_ptr(ptr: *const c_void) -> Result<Self> {
95        if ptr.is_null() {
96            return Ok(Node::None);
97        }
98
99        let node = unsafe { &mut *(ptr as *mut mpv_node) };
100        let result = from_mpv_node(node);
101        unsafe { mpv_free_node_contents(node) };
102        Ok(result)
103    }
104
105    fn to_mpv<F: Fn(*mut c_void) -> Result<()>>(self, fun: F) -> Result<()> {
106        let mpv_node_ptr = to_mpv_node(&self);
107        let res = fun(mpv_node_ptr as *mut c_void);
108        unsafe { mpv_free_node_contents(mpv_node_ptr) };
109        res
110    }
111
112    fn from_mpv<F: Fn(*mut c_void) -> Result<()>>(fun: F) -> Result<Self> {
113        let mut node = mpv_node {
114            format: mpv_format_MPV_FORMAT_NONE,
115            u: mpv_node__bindgen_ty_1 { int64: 0 },
116        };
117
118        fun(&mut node as *mut _ as *mut c_void)?;
119        let result = from_mpv_node(&mut node);
120        unsafe { mpv_free_node_contents(&mut node) };
121        Ok(result)
122    }
123}