1mod device_property;
3use std::fmt;
4
5use crate::device::device_property::PropertyValue;
6use crate::error::{OrbbecError, OrbbecErrorData};
7use crate::{Context, DeviceType, PermissionType, sys};
8
9#[doc(inline)]
10pub use device_property::DeviceProperty;
11
12pub struct DeviceInfo {
14 inner: sys::device::OBDeviceInfo,
15}
16
17impl DeviceInfo {
18 pub(crate) fn new(inner: sys::device::OBDeviceInfo) -> Self {
19 DeviceInfo { inner }
20 }
21
22 pub fn name(&self) -> String {
24 let cstr = self.inner.get_name().unwrap();
28
29 cstr.to_string_lossy().into_owned()
30 }
31
32 pub fn pid(&self) -> u16 {
34 self.inner.get_pid().unwrap() as u16
38 }
39
40 pub fn vid(&self) -> u16 {
42 self.inner.get_vid().unwrap() as u16
46 }
47
48 pub fn uid(&self) -> String {
50 let cstr = self.inner.get_uid().unwrap();
54
55 cstr.to_string_lossy().into_owned()
56 }
57
58 pub fn serial_number(&self) -> String {
60 let cstr = self.inner.get_serial_number().unwrap();
64
65 cstr.to_string_lossy().into_owned()
66 }
67
68 pub fn firmware_version(&self) -> String {
70 let cstr = self.inner.get_firmware_version().unwrap();
74
75 cstr.to_string_lossy().into_owned()
76 }
77
78 pub fn hardware_version(&self) -> String {
80 let cstr = self.inner.get_hardware_version().unwrap();
84
85 cstr.to_string_lossy().into_owned()
86 }
87
88 pub fn connection_type(&self) -> String {
90 let cstr = self.inner.get_connection_type().unwrap();
94
95 cstr.to_string_lossy().into_owned()
96 }
97
98 pub fn minimum_supported_sdk_version(&self) -> String {
100 let cstr = self.inner.get_min_supported_sdk_version().unwrap();
104
105 cstr.to_string_lossy().into_owned()
106 }
107
108 pub fn asic_name(&self) -> String {
110 let cstr = self.inner.get_asic_name().unwrap();
114
115 cstr.to_string_lossy().into_owned()
116 }
117
118 pub fn device_type(&self) -> DeviceType {
120 self.inner.get_device_type().unwrap()
124 }
125}
126
127impl fmt::Debug for DeviceInfo {
128 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
129 f.debug_struct("DeviceInfo")
130 .field("name", &self.name())
131 .field("pid", &format_args!("{:04X}", self.pid()))
132 .field("vid", &format_args!("{:04X}", self.vid()))
133 .field("uid", &self.uid())
134 .field("serial_number", &self.serial_number())
135 .field("firmware_version", &self.firmware_version())
136 .field("hardware_version", &self.hardware_version())
137 .field("connection_type", &self.connection_type())
138 .field(
139 "minimum_supported_sdk_version",
140 &self.minimum_supported_sdk_version(),
141 )
142 .field("asic_name", &self.asic_name())
143 .field("device_type", &self.device_type())
144 .finish()
145 }
146}
147
148pub struct Device {
150 inner: sys::device::OBDevice,
151}
152
153impl Device {
154 pub(crate) fn new(inner: sys::device::OBDevice) -> Self {
155 Device { inner }
156 }
157
158 pub(crate) fn inner(&self) -> &sys::device::OBDevice {
159 &self.inner
160 }
161
162 pub fn info(&self) -> Result<DeviceInfo, OrbbecError> {
164 let info = self.inner.get_info().map_err(OrbbecError::from)?;
165
166 Ok(DeviceInfo::new(info))
167 }
168
169 pub fn load_preset(&mut self, preset_name: &str) -> Result<(), OrbbecError> {
173 let cstr = std::ffi::CString::new(preset_name).map_err(|e| {
174 let err_data = OrbbecErrorData {
175 message: format!("Invalid preset name: {e}"),
176 function: "Device::load_preset".to_string(),
177 args: preset_name.to_string(),
178 };
179
180 OrbbecError::InvalidValue(err_data)
181 })?;
182
183 self.inner.load_preset(&cstr).map_err(OrbbecError::from)
184 }
185
186 pub fn is_property_supported(
191 &self,
192 property: DeviceProperty,
193 permission: PermissionType,
194 ) -> Result<bool, OrbbecError> {
195 let mut property = property;
196 let (prop_id, _) = property.decompose();
197
198 self.inner
199 .is_property_supported(prop_id, permission)
200 .map_err(OrbbecError::from)
201 }
202
203 pub fn set_property(&mut self, property: DeviceProperty) -> Result<(), OrbbecError> {
207 let mut property = property;
208 let (prop_id, prop_type) = property.decompose();
209
210 match prop_type {
211 PropertyValue::Bool(value) => self
212 .inner
213 .set_bool_property(prop_id, *value)
214 .map_err(OrbbecError::from),
215 PropertyValue::Int(value) => self
216 .inner
217 .set_int_property(prop_id, *value)
218 .map_err(OrbbecError::from),
219 PropertyValue::Float(value) => self
220 .inner
221 .set_float_property(prop_id, *value)
222 .map_err(OrbbecError::from),
223 }
224 }
225
226 pub fn get_property(&self, property: &mut DeviceProperty) -> Result<(), OrbbecError> {
230 let (prop_id, prop_type) = property.decompose();
231
232 match prop_type {
233 PropertyValue::Bool(value) => {
234 *value = self
235 .inner
236 .get_bool_property(prop_id)
237 .map_err(OrbbecError::from)?;
238 }
239 PropertyValue::Int(value) => {
240 *value = self
241 .inner
242 .get_int_property(prop_id)
243 .map_err(OrbbecError::from)?;
244 }
245 PropertyValue::Float(value) => {
246 *value = self
247 .inner
248 .get_float_property(prop_id)
249 .map_err(OrbbecError::from)?;
250 }
251 }
252 Ok(())
253 }
254}
255
256pub struct DeviceList<'a> {
258 inner: sys::device::OBDeviceList,
259 _context: &'a Context,
261}
262
263impl<'a> DeviceList<'a> {
264 pub(crate) fn new(inner: sys::device::OBDeviceList, context: &'a Context) -> Self {
265 DeviceList {
266 inner,
267 _context: context,
268 }
269 }
270
271 pub fn len(&self) -> usize {
273 self.inner.get_count().unwrap() as usize
277 }
278
279 pub fn is_empty(&self) -> bool {
281 self.len() == 0
282 }
283
284 pub fn get(&self, index: usize) -> Result<Device, OrbbecError> {
288 let device = self.inner.get_device(index as u32);
289
290 device.map(Device::new).map_err(OrbbecError::from)
291 }
292}
293
294pub struct DeviceListIterator<'a, 'b> {
295 device_list: &'b DeviceList<'a>,
296 index: usize,
297 count: usize,
298}
299
300impl<'a, 'b> DeviceListIterator<'a, 'b> {
301 pub fn new(device_list: &'a DeviceList<'b>) -> Result<Self, OrbbecError> {
302 Ok(DeviceListIterator {
303 device_list,
304 index: 0,
305 count: device_list.len(),
306 })
307 }
308}
309
310impl<'a, 'b> Iterator for DeviceListIterator<'a, 'b> {
311 type Item = Result<Device, OrbbecError>;
312
313 fn next(&mut self) -> Option<Self::Item> {
314 if self.index >= self.count {
315 None
316 } else {
317 let device = self.device_list.get(self.index);
318 self.index += 1;
319 Some(device)
320 }
321 }
322}
323
324impl<'a, 'b> IntoIterator for &'b DeviceList<'a>
325where
326 'b: 'a,
327{
328 type Item = Result<Device, OrbbecError>;
329 type IntoIter = DeviceListIterator<'a, 'b>;
330
331 fn into_iter(self) -> Self::IntoIter {
332 DeviceListIterator::<'a, 'b>::new(self).unwrap()
333 }
334}