orbbec-sdk 0.1.0

High-level bindings to Orbbec SDK v2
Documentation
//! Low-level bindings to the Orbbec SDK C API.
//! All unsafe code interacting with the C API is contained in this module.

pub mod context;
pub mod device;
pub mod enums;
pub mod filter;
pub mod frame;
pub mod pipeline;
pub mod stream;

/// Internal module containing the raw bindings generated by bindgen.
mod orb {
    #![allow(non_upper_case_globals)]
    #![allow(non_camel_case_types)]
    #![allow(non_snake_case)]
    #![allow(unused)]

    include!("../bindings/bindings.rs");
}

macro_rules! drop_ob_object {
    ($name:ident, $delete_fn:ident) => {
        impl Drop for $name {
            fn drop(&mut self) {
                if !self.inner.is_null() {
                    let mut err_ptr = std::ptr::null_mut();

                    unsafe {
                        orb::$delete_fn(self.inner, &mut err_ptr);
                    }

                    // Error is ignored as we can't do anything about it
                    let _ = OBError::consume(err_ptr);
                }
            }
        }
    };
}

use drop_ob_object;

use crate::sys::enums::OBExceptionType;

/// The error class exposed by the SDK, users can get detailed error information according to the error
pub struct OBError {
    inner: *mut orb::ob_error,
}

impl std::fmt::Debug for OBError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        unsafe {
            let error = &*self.inner;
            let status = error.status;
            let exception_type = error.exception_type;

            write!(
                f,
                "OBError {{ status: {:?}, message: {:?}, function: {:?}, args: {:?}, exception_type: {:?} }}",
                status,
                std::ffi::CStr::from_ptr(error.message.as_ptr()).to_string_lossy(),
                std::ffi::CStr::from_ptr(error.function.as_ptr()).to_string_lossy(),
                std::ffi::CStr::from_ptr(error.args.as_ptr()).to_string_lossy(),
                exception_type
            )
        }
    }
}

impl std::fmt::Display for OBError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        unsafe {
            let error = &*self.inner;

            write!(
                f,
                "OBError: {:?}",
                std::ffi::CStr::from_ptr(error.message.as_ptr()).to_string_lossy(),
            )
        }
    }
}

impl std::error::Error for OBError {}

impl OBError {
    /// Get the error message
    pub fn message(&self) -> String {
        unsafe {
            let error = &*self.inner;
            std::ffi::CStr::from_ptr(error.message.as_ptr())
                .to_string_lossy()
                .into_owned()
        }
    }

    /// Get the function name where the error occurred
    pub fn function(&self) -> String {
        unsafe {
            let error = &*self.inner;
            std::ffi::CStr::from_ptr(error.function.as_ptr())
                .to_string_lossy()
                .into_owned()
        }
    }

    /// Get the arguments of the function where the error occurred
    pub fn args(&self) -> String {
        unsafe {
            let error = &*self.inner;
            std::ffi::CStr::from_ptr(error.args.as_ptr())
                .to_string_lossy()
                .into_owned()
        }
    }

    /// Get the exception type of the error
    pub fn exception_type(&self) -> OBExceptionType {
        unsafe {
            let error = &*self.inner;
            error.exception_type.into()
        }
    }

    /// Consume the pointer and return an error if it exists
    pub fn consume(error: *mut orb::ob_error) -> Result<(), Self> {
        // No error provided
        if error.is_null() {
            return Ok(());
        }

        // Status is OK, no error to report
        let status = unsafe { (*error).status };
        if status == orb::OBStatus_OB_STATUS_OK {
            unsafe { orb::ob_delete_error(error) };
            return Ok(());
        }

        Err(OBError { inner: error })
    }
}

impl Drop for OBError {
    fn drop(&mut self) {
        if !self.inner.is_null() {
            unsafe {
                orb::ob_delete_error(self.inner);
            }
        }
    }
}