libobs_wrapper\data/
traits.rs1use std::ffi::CStr;
2
3use libobs::obs_data;
4
5use crate::{
6 data::ObsData,
7 run_with_obs,
8 runtime::ObsRuntime,
9 unsafe_send::Sendable,
10 utils::{ObsError, ObsString},
11};
12
13impl ObsDataGetters for ObsData {
14 fn runtime(&self) -> &ObsRuntime {
15 &self.runtime
16 }
17
18 fn as_ptr(&self) -> Sendable<*mut obs_data> {
19 self.obs_data.clone()
20 }
21}
22
23pub trait ObsDataGetters {
24 fn runtime(&self) -> &ObsRuntime;
25 fn as_ptr(&self) -> Sendable<*mut obs_data>;
26 fn get_string<T: Into<ObsString> + Send + Sync>(
27 &self,
28 key: T,
29 ) -> Result<Option<String>, ObsError> {
30 let key = key.into();
31
32 let key_ptr = key.as_ptr();
33 let data_ptr = self.as_ptr();
34
35 let result = run_with_obs!(self.runtime(), (data_ptr, key_ptr), move || unsafe {
36 if libobs::obs_data_has_user_value(data_ptr, key_ptr)
37 || libobs::obs_data_has_default_value(data_ptr, key_ptr)
38 {
39 Some(Sendable(libobs::obs_data_get_string(data_ptr, key_ptr)))
40 } else {
41 None
42 }
43 })?;
44
45 if result.is_none() {
46 return Ok(None);
47 }
48
49 let result = result.unwrap();
50 if result.0.is_null() {
51 return Err(ObsError::NullPointer);
52 }
53
54 let result = unsafe { CStr::from_ptr(result.0) };
55 let result = result
56 .to_str()
57 .map_err(|_| ObsError::StringConversionError)?;
58
59 Ok(Some(result.to_string()))
60 }
61 fn get_int<T: Into<ObsString> + Sync + Send>(&self, key: T) -> Result<Option<i64>, ObsError> {
62 let key = key.into();
63
64 let key_ptr = key.as_ptr();
65 let data_ptr = self.as_ptr();
66
67 let result = run_with_obs!(self.runtime(), (data_ptr, key_ptr), move || unsafe {
68 if libobs::obs_data_has_user_value(data_ptr, key_ptr)
69 || libobs::obs_data_has_default_value(data_ptr, key_ptr)
70 {
71 Some(libobs::obs_data_get_int(data_ptr, key_ptr))
72 } else {
73 None
74 }
75 })?;
76
77 Ok(result)
78 }
79 fn get_bool<T: Into<ObsString> + Sync + Send>(&self, key: T) -> Result<Option<bool>, ObsError> {
80 let key = key.into();
81
82 let key_ptr = key.as_ptr();
83 let data_ptr = self.as_ptr();
84
85 let result = run_with_obs!(self.runtime(), (data_ptr, key_ptr), move || unsafe {
86 if libobs::obs_data_has_user_value(data_ptr, key_ptr)
87 || libobs::obs_data_has_default_value(data_ptr, key_ptr)
88 {
89 Some(libobs::obs_data_get_bool(data_ptr, key_ptr))
90 } else {
91 None
92 }
93 })?;
94
95 Ok(result)
96 }
97 fn get_double<T: Into<ObsString> + Sync + Send>(
98 &self,
99 key: T,
100 ) -> Result<Option<f64>, ObsError> {
101 let key = key.into();
102
103 let key_ptr = key.as_ptr();
104 let data_ptr = self.as_ptr();
105
106 let result = run_with_obs!(self.runtime(), (key_ptr, data_ptr), move || unsafe {
107 if libobs::obs_data_has_user_value(data_ptr, key_ptr)
108 || libobs::obs_data_has_default_value(data_ptr, key_ptr)
109 {
110 Some(libobs::obs_data_get_double(data_ptr, key_ptr))
111 } else {
112 None
113 }
114 })?;
115
116 Ok(result)
117 }
118
119 fn get_json(&self) -> Result<String, ObsError> {
120 let data_ptr = self.as_ptr();
121 let ptr = run_with_obs!(self.runtime(), (data_ptr), move || unsafe {
122 Sendable(libobs::obs_data_get_json(data_ptr))
123 })?;
124
125 if ptr.0.is_null() {
126 return Err(ObsError::NullPointer);
127 }
128
129 let ptr = unsafe { CStr::from_ptr(ptr.0) };
130 let ptr = ptr.to_str().map_err(|_| ObsError::JsonParseError)?;
131
132 Ok(ptr.to_string())
133 }
134}