libcamera/
utils.rs

1use std::{
2    ffi::c_int,
3    io,
4    ops::{Deref, DerefMut},
5    ptr::NonNull,
6};
7
8/// Provides only an immutable reference to the contained type T.
9///
10/// Used for FFI types to avoid having separate variants depending on mutability.
11pub struct Immutable<T: ?Sized>(pub(crate) T);
12
13impl<T> Immutable<T> {
14    pub fn value(&self) -> &T {
15        &self.0
16    }
17}
18
19impl<T> Deref for Immutable<T> {
20    type Target = T;
21
22    fn deref(&self) -> &Self::Target {
23        &self.0
24    }
25}
26
27impl<T: core::fmt::Debug> core::fmt::Debug for Immutable<T> {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29        f.debug_tuple("Immutable").field(&self.0).finish()
30    }
31}
32
33/// Trait, which allows type to be used in [UniquePtr]
34pub trait UniquePtrTarget: Sized {
35    /// Allocates `Self` in the heap and returns pointer.
36    ///
37    /// # Safety
38    ///
39    /// Pointer must be deallocated by calling [Self::ptr_drop()] when no longer needed.
40    unsafe fn ptr_new() -> *mut Self;
41    /// Destroys pointer allocated in `ptr_new()`.
42    ///
43    /// # Safety
44    ///
45    /// Pointer must have been created by [Self::ptr_new()] and is no longer aliased.
46    unsafe fn ptr_drop(ptr: *mut Self);
47}
48
49/// Similar to [Box], but uses custom alloc and drop methods defined in [UniquePtrTarget].
50pub struct UniquePtr<T: UniquePtrTarget> {
51    ptr: NonNull<T>,
52}
53
54impl<T: UniquePtrTarget> UniquePtr<T> {
55    pub fn new() -> Self {
56        Self {
57            ptr: NonNull::new(unsafe { T::ptr_new() }).unwrap(),
58        }
59    }
60}
61
62impl<T: UniquePtrTarget> Default for UniquePtr<T> {
63    fn default() -> Self {
64        Self::new()
65    }
66}
67
68impl<T: UniquePtrTarget> Deref for UniquePtr<T> {
69    type Target = T;
70
71    fn deref(&self) -> &Self::Target {
72        unsafe { &*(self.ptr.as_ptr() as *const T) }
73    }
74}
75
76impl<T: UniquePtrTarget> DerefMut for UniquePtr<T> {
77    fn deref_mut(&mut self) -> &mut Self::Target {
78        unsafe { &mut *(self.ptr.as_mut() as *mut T) }
79    }
80}
81
82impl<T: UniquePtrTarget> Drop for UniquePtr<T> {
83    fn drop(&mut self) {
84        unsafe { T::ptr_drop(self.ptr.as_mut()) }
85    }
86}
87
88impl<T: UniquePtrTarget + core::fmt::Debug> core::fmt::Debug for UniquePtr<T> {
89    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90        self.deref().fmt(f)
91    }
92}
93
94#[inline]
95pub fn handle_result(ret: c_int) -> io::Result<()> {
96    if ret < 0 {
97        Err(io::Error::from_raw_os_error(ret))
98    } else {
99        Ok(())
100    }
101}