realsense_rust/
context.rs1use crate::{
4 base::from_path,
5 check_rs2_error,
6 device::Device,
7 device_hub::DeviceHub,
8 kind::{Rs2Exception, Rs2ProductLine},
9};
10use anyhow::Result;
11use num_traits::ToPrimitive;
12use realsense_sys as sys;
13use std::{collections::HashSet, convert::From, path::Path, ptr::NonNull};
14use thiserror::Error;
15
16#[derive(Debug)]
18pub struct Context {
19 context_ptr: NonNull<sys::rs2_context>,
21}
22
23#[derive(Error, Debug)]
25#[error("Could not construct the context. Type: {0}; Reason: {1}")]
26pub struct ContextConstructionError(pub Rs2Exception, pub String);
27
28#[derive(Error, Debug)]
30#[error("Could not get the device hub from the context. Type: {0}; Reason: {1}")]
31pub struct CouldNotGetDeviceHubError(pub Rs2Exception, pub String);
32
33#[derive(Error, Debug)]
35#[error("Could not add a device from file. Type: {0}; Reason: {1}")]
36pub struct CouldNotAddDeviceError(pub Rs2Exception, pub String);
37
38#[derive(Error, Debug)]
40#[error("Could not remove device from file. Type: {0}; Reason: {1}")]
41pub struct CouldNotRemoveDeviceError(pub Rs2Exception, pub String);
42
43impl Drop for Context {
44 fn drop(&mut self) {
45 unsafe { sys::rs2_delete_context(self.context_ptr.as_ptr()) }
46 }
47}
48
49unsafe impl Send for Context {}
50
51impl Context {
52 pub fn new() -> Result<Self, ContextConstructionError> {
59 unsafe {
60 let mut err = std::ptr::null_mut::<sys::rs2_error>();
61 let ptr = sys::rs2_create_context(sys::RS2_API_VERSION as i32, &mut err);
62 check_rs2_error!(err, ContextConstructionError)?;
63
64 Ok(Self {
65 context_ptr: NonNull::new(ptr).unwrap(),
66 })
67 }
68 }
69
70 pub fn create_device_hub(&self) -> Result<DeviceHub, CouldNotGetDeviceHubError> {
77 unsafe {
78 let mut err = std::ptr::null_mut::<sys::rs2_error>();
79 let devicehub_ptr = sys::rs2_create_device_hub(self.context_ptr.as_ptr(), &mut err);
80 check_rs2_error!(err, CouldNotGetDeviceHubError)?;
81
82 Ok(DeviceHub::from(NonNull::new(devicehub_ptr).unwrap()))
83 }
84 }
85
86 pub fn query_devices(&self, product_mask: HashSet<Rs2ProductLine>) -> Vec<Device> {
88 let mask = if product_mask.is_empty() {
92 Rs2ProductLine::Any.to_i32().unwrap()
93 } else {
94 product_mask.iter().fold(0, |k, v| k | v.to_u32().unwrap()) as i32
95 };
96
97 let mut devices = Vec::new();
98 unsafe {
99 let mut err = std::ptr::null_mut::<sys::rs2_error>();
100 let device_list_ptr =
101 sys::rs2_query_devices_ex(self.context_ptr.as_ptr(), mask, &mut err);
102
103 if err.as_ref().is_some() {
104 sys::rs2_free_error(err);
105 return devices;
106 }
107
108 let device_list = NonNull::new(device_list_ptr).unwrap();
109
110 let len = sys::rs2_get_device_count(device_list.as_ptr(), &mut err);
111
112 if err.as_ref().is_some() {
113 sys::rs2_free_error(err);
114 sys::rs2_delete_device_list(device_list.as_ptr());
115 return devices;
116 }
117
118 for i in 0..len {
119 match Device::try_create(&device_list, i) {
120 Ok(d) => {
121 devices.push(d);
122 }
123 Err(_) => {
124 continue;
125 }
126 }
127 }
128
129 sys::rs2_delete_device_list(device_list.as_ptr());
130 }
131 devices
132 }
133
134 pub fn add_device<P>(&mut self, file: P) -> Result<Device>
149 where
150 P: AsRef<Path>,
151 {
152 let path = from_path(file)?;
153 unsafe {
154 let mut err = std::ptr::null_mut::<sys::rs2_error>();
155 let device_ptr =
156 sys::rs2_context_add_device(self.context_ptr.as_ptr(), path.as_ptr(), &mut err);
157 check_rs2_error!(err, CouldNotAddDeviceError)?;
158
159 Ok(Device::from(NonNull::new(device_ptr).unwrap()))
160 }
161 }
162
163 pub fn remove_device<P>(&mut self, file: P) -> Result<()>
173 where
174 P: AsRef<Path>,
175 {
176 let path = from_path(file)?;
177 unsafe {
178 let mut err = std::ptr::null_mut::<sys::rs2_error>();
179 sys::rs2_context_remove_device(self.context_ptr.as_ptr(), path.as_ptr(), &mut err);
180 check_rs2_error!(err, CouldNotRemoveDeviceError)?;
181
182 Ok(())
183 }
184 }
185
186 pub(crate) unsafe fn get_raw(&self) -> NonNull<sys::rs2_context> {
195 self.context_ptr
196 }
197}