libmpv_client/types/
basics.rs

1use std::ffi::{CStr, CString, c_char, c_int, c_void};
2use std::ptr::null_mut;
3use crate::*;
4use crate::types::traits::{MpvFormat, MpvRecv, MpvRecvInternal, MpvSend, MpvSendInternal};
5
6/// A wrapper around [`String`] for mpv OSD property strings. See [`Format::OSD_STRING`].
7///
8/// It represents an OSD property string, like using `${property}` in `input.conf`.
9/// See [the mpv docs on raw and formatted properties](https://mpv.io/manual/stable/#raw-and-formatted-properties).
10///
11/// In many cases, this is the same as the raw string, but in other cases it's formatted for display on OSD.
12///
13/// It's intended to be human-readable. Do not attempt to parse these strings.
14#[derive(Debug)]
15pub struct OsdString(pub String);
16
17impl MpvFormat for String {
18    const MPV_FORMAT: Format = Format::STRING;
19}
20
21impl From<String> for Node {
22    fn from(value: String) -> Self {
23        Node::String(value)
24    }
25}
26
27impl From<&String> for Node {
28    fn from(value: &String) -> Self {
29        Node::String(value.clone())
30    }
31}
32
33impl From<&str> for Node {
34    fn from(value: &str) -> Self {
35        Node::String(value.to_string())
36    }
37}
38
39impl MpvRecv for String {}
40impl MpvRecvInternal for String {
41    unsafe fn from_ptr(ptr: *const c_void) -> Result<Self> {
42        check_null!(ptr);
43        let cstr = unsafe { *(ptr as *const *const c_char) };
44
45        check_null!(cstr);
46        Ok(unsafe { CStr::from_ptr(cstr) }.to_str()?.to_string())
47    }
48
49    unsafe fn from_mpv<F: Fn(*mut c_void) -> Result<i32>>(fun: F) -> Result<Self> {
50        let mut cstr: *mut c_char = null_mut();
51
52        fun(&raw mut cstr as *mut c_void).and_then(|_| {
53            let ret = unsafe { Self::from_ptr(&raw mut cstr as *const c_void) };
54            unsafe { mpv_free(cstr as *mut c_void) }
55            ret
56        })
57    }
58}
59
60impl MpvSend for String {}
61impl MpvSendInternal for String {
62    fn to_mpv<F: Fn(*mut c_void) -> Result<i32>>(&self, fun: F) -> Result<i32> {
63        let cstring = CString::new(self.as_bytes())?;
64        let cstr = cstring.as_ptr();
65
66        fun(&raw const cstr as *mut c_void)
67    }
68}
69
70impl MpvFormat for &str {
71    const MPV_FORMAT: Format = Format::STRING;
72}
73
74impl MpvSend for &str {}
75impl MpvSendInternal for &str {
76    fn to_mpv<F: Fn(*mut c_void) -> Result<i32>>(&self, fun: F) -> Result<i32> {
77        let cstring = CString::new(*self)?;
78        let cstr = cstring.as_ptr();
79
80        fun(&raw const cstr as *mut c_void)
81    }
82}
83
84impl MpvFormat for OsdString {
85    const MPV_FORMAT: Format = Format::OSD_STRING;
86}
87
88impl MpvRecv for OsdString {}
89impl MpvRecvInternal for OsdString {
90    unsafe fn from_ptr(ptr: *const c_void) -> Result<Self> {
91        Ok(OsdString(unsafe { String::from_ptr(ptr)? }))
92    }
93
94    unsafe fn from_mpv<F: Fn(*mut c_void) -> Result<i32>>(fun: F) -> Result<Self> {
95        unsafe { String::from_mpv(fun) }.map(Self)
96    }
97}
98
99impl MpvSend for OsdString {}
100impl MpvSendInternal for OsdString {
101    fn to_mpv<F: Fn(*mut c_void) -> Result<i32>>(&self, fun: F) -> Result<i32> {
102        self.0.to_mpv(fun)
103    }
104}
105
106impl MpvFormat for bool {
107    const MPV_FORMAT: Format = Format::FLAG;
108}
109
110impl From<bool> for Node {
111    fn from(value: bool) -> Self {
112        Node::Flag(value)
113    }
114}
115
116impl MpvRecv for bool {}
117impl MpvRecvInternal for bool {
118    unsafe fn from_ptr(ptr: *const c_void) -> Result<Self> {
119        check_null!(ptr);
120        Ok(unsafe { *(ptr as *const c_int) != 0 })
121    }
122
123    unsafe fn from_mpv<F: Fn(*mut c_void) -> Result<i32>>(fun: F) -> Result<Self> {
124        let mut flag: c_int = 0;
125        fun(&raw mut flag as *mut c_void).map(|_| flag != 0)
126    }
127}
128
129impl MpvSend for bool {}
130impl MpvSendInternal for bool {
131    fn to_mpv<F: Fn(*mut c_void) -> Result<i32>>(&self, fun: F) -> Result<i32> {
132        let flag = if *self { 1 } else { 0 };
133        fun(&raw const flag as *mut c_void)
134    }
135}
136
137impl MpvFormat for i64 {
138    const MPV_FORMAT: Format = Format::INT64;
139}
140
141impl From<i64> for Node {
142    fn from(value: i64) -> Self {
143        Node::Int64(value)
144    }
145}
146
147impl MpvRecv for i64 {}
148impl MpvRecvInternal for i64 {
149    unsafe fn from_ptr(ptr: *const c_void) -> Result<Self> {
150        check_null!(ptr);
151        Ok(unsafe { *(ptr as *const Self) })
152    }
153
154    unsafe fn from_mpv<F: Fn(*mut c_void) -> Result<i32>>(fun: F) -> Result<Self> {
155        let mut val: Self = 0;
156        fun(&raw mut val as *mut c_void).map(|_| val)
157    }
158}
159
160impl MpvSend for i64 {}
161impl MpvSendInternal for i64 {
162    fn to_mpv<F: Fn(*mut c_void) -> Result<i32>>(&self, fun: F) -> Result<i32> {
163        fun(self as *const Self as *mut c_void)
164    }
165}
166
167impl MpvFormat for f64 {
168    const MPV_FORMAT: Format = Format::DOUBLE;
169}
170
171impl From<f64> for Node {
172    fn from(value: f64) -> Self {
173        Node::Double(value)
174    }
175}
176
177impl MpvRecv for f64 {}
178impl MpvRecvInternal for f64 {
179    unsafe fn from_ptr(ptr: *const c_void) -> Result<Self> {
180        check_null!(ptr);
181        Ok(unsafe { *(ptr as *const Self) })
182    }
183
184    unsafe fn from_mpv<F: Fn(*mut c_void) -> Result<i32>>(fun: F) -> Result<Self> {
185        let mut val: Self = 0.0;
186        fun(&raw mut val as *mut c_void).map(|_| val)
187    }
188}
189
190impl MpvSend for f64 {}
191impl MpvSendInternal for f64 {
192    fn to_mpv<F: Fn(*mut c_void) -> Result<i32>>(&self, fun: F) -> Result<i32> {
193        fun(self as *const Self as *mut c_void)
194    }
195}