mpv_client_cross/
format.rs1use 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}