libobs_wrapper\data\traits/
getters.rs1use std::ffi::CStr;
2
3use crate::{
4 data::ObsDataPointers,
5 run_with_obs,
6 unsafe_send::SmartPointerSendable,
7 utils::{ObsError, ObsString},
8};
9
10#[allow(unknown_lints)]
13#[allow(ensure_obs_call_in_runtime)]
14unsafe fn has_value(
15 data_ptr: SmartPointerSendable<*mut libobs::obs_data_t>,
16 key: &ObsString,
17) -> bool {
18 libobs::obs_data_has_user_value(data_ptr.get_ptr(), key.as_ptr().0)
19 || libobs::obs_data_has_default_value(data_ptr.get_ptr(), key.as_ptr().0)
20}
21
22pub trait ObsDataGetters: ObsDataPointers {
23 fn get_string<T: Into<ObsString> + Send + Sync>(
24 &self,
25 key: T,
26 ) -> Result<Option<String>, ObsError> {
27 let key = key.into();
28 let data_ptr = self.as_ptr();
29
30 run_with_obs!(self.runtime(), (data_ptr, key), move || {
31 let has_value = unsafe {
32 has_value(data_ptr.clone(), &key)
34 };
35
36 if has_value {
37 let result = unsafe {
38 libobs::obs_data_get_string(data_ptr.get_ptr(), key.as_ptr().0)
40 };
41
42 if result.is_null() {
43 Err(ObsError::NullPointer(None))
44 } else {
45 let result = unsafe {
46 CStr::from_ptr(result)
48 };
49 let result = result
50 .to_str()
51 .map_err(|_| ObsError::StringConversionError)?
52 .to_string();
53
54 Ok(Some(result))
55 }
56 } else {
57 Ok(None)
58 }
59 })?
60 }
61 fn get_int<T: Into<ObsString> + Sync + Send>(&self, key: T) -> Result<Option<i64>, ObsError> {
62 let key = key.into();
63 let data_ptr = self.as_ptr();
64
65 run_with_obs!(self.runtime(), (data_ptr, key), move || {
66 let has_value = unsafe {
67 has_value(data_ptr.clone(), &key)
69 };
70
71 if has_value {
72 Some(unsafe {
73 libobs::obs_data_get_int(data_ptr.get_ptr(), key.as_ptr().0)
75 })
76 } else {
77 None
78 }
79 })
80 }
81 fn get_bool<T: Into<ObsString> + Sync + Send>(&self, key: T) -> Result<Option<bool>, ObsError> {
82 let key = key.into();
83
84 let data_ptr = self.as_ptr();
85
86 run_with_obs!(self.runtime(), (data_ptr, key), move || {
87 let has_value = unsafe {
88 has_value(data_ptr.clone(), &key)
90 };
91
92 if has_value {
93 Some(unsafe {
94 libobs::obs_data_get_bool(data_ptr.get_ptr(), key.as_ptr().0)
96 })
97 } else {
98 None
99 }
100 })
101 }
102 fn get_double<T: Into<ObsString> + Sync + Send>(
103 &self,
104 key: T,
105 ) -> Result<Option<f64>, ObsError> {
106 let key = key.into();
107 let data_ptr = self.as_ptr();
108
109 let result = run_with_obs!(self.runtime(), (key, data_ptr), move || {
110 let has_value = unsafe {
111 has_value(data_ptr.clone(), &key)
113 };
114
115 if has_value {
116 Some(unsafe {
117 libobs::obs_data_get_double(data_ptr.get_ptr(), key.as_ptr().0)
119 })
120 } else {
121 None
122 }
123 })?;
124
125 Ok(result)
126 }
127
128 fn get_json(&self) -> Result<String, ObsError> {
129 let data_ptr = self.as_ptr();
130 run_with_obs!(self.runtime(), (data_ptr), move || {
131 let json_ptr = unsafe {
132 libobs::obs_data_get_json(data_ptr.get_ptr())
134 };
135
136 if json_ptr.is_null() {
137 return Err(ObsError::NullPointer(Some(
138 "Couldn't get json representation of OBS data".into(),
139 )));
140 }
141
142 let json = unsafe {
143 CStr::from_ptr(json_ptr)
145 }
146 .to_str()
147 .map_err(|_| ObsError::JsonParseError)?
148 .to_string();
149
150 Ok(json)
151 })?
152 }
153}