use crate::{check_rs2_error, device::Device, kind::Rs2Exception};
use anyhow::Result;
use realsense_sys as sys;
use std::{convert::From, ptr::NonNull};
use thiserror::Error;
#[derive(Error, Debug)]
#[error("Could not wait for device due to internal error. Type: {0}; Reason: {1}")]
pub struct CouldNotWaitForDeviceError(pub Rs2Exception, pub String);
#[derive(Debug)]
pub struct DeviceHub {
devicehub_ptr: NonNull<sys::rs2_device_hub>,
}
impl Drop for DeviceHub {
fn drop(&mut self) {
unsafe {
sys::rs2_delete_device_hub(self.devicehub_ptr.as_ptr());
}
}
}
unsafe impl Send for DeviceHub {}
impl From<NonNull<sys::rs2_device_hub>> for DeviceHub {
fn from(devicehub_ptr: NonNull<sys::rs2_device_hub>) -> Self {
Self { devicehub_ptr }
}
}
impl DeviceHub {
pub fn wait_for_device(&self) -> Result<Device> {
unsafe {
let mut err = std::ptr::null_mut::<sys::rs2_error>();
let device_ptr =
sys::rs2_device_hub_wait_for_device(self.devicehub_ptr.as_ptr(), &mut err);
check_rs2_error!(err, CouldNotWaitForDeviceError)?;
Ok(Device::from(NonNull::new(device_ptr).unwrap()))
}
}
pub fn is_device_connected(&self, device: &Device) -> bool {
unsafe {
let mut err = std::ptr::null_mut::<sys::rs2_error>();
let val = sys::rs2_device_hub_is_device_connected(
self.devicehub_ptr.as_ptr(),
device.get_raw().as_ptr(),
&mut err,
);
if err.as_ref().is_none() {
val != 0
} else {
sys::rs2_free_error(err);
false
}
}
}
}