flipperzero_sys/furi/record.rs
1//! Low-level wrappers around Furi Record API.
2
3use core::ffi::CStr;
4use core::ptr::NonNull;
5
6/// Low-level wrapper of a record handle.
7///
8/// This effectively acts as a reference count for the open underlying Record.
9pub struct UnsafeRecord<T> {
10 name: &'static CStr,
11 raw: NonNull<T>,
12}
13
14impl<T> UnsafeRecord<T> {
15 /// Opens a record.
16 ///
17 /// # Safety
18 ///
19 /// `T` must be the correct C type for the record identified by `name`.
20 pub unsafe fn open(name: &'static CStr) -> Self {
21 Self {
22 name,
23 // SAFETY: `furi_record_open` blocks until the record is initialized with a valid value.
24 raw: unsafe { NonNull::new_unchecked(crate::furi_record_open(name.as_ptr()).cast()) },
25 }
26 }
27
28 /// Returns the record data as a raw pointer.
29 pub fn as_ptr(&self) -> *mut T {
30 self.raw.as_ptr()
31 }
32}
33
34impl<T> Clone for UnsafeRecord<T> {
35 fn clone(&self) -> Self {
36 // SAFETY: Opening a record multiple times just increases its reference count.
37 unsafe { Self::open(self.name) }
38 }
39}
40
41impl<T> Drop for UnsafeRecord<T> {
42 fn drop(&mut self) {
43 unsafe {
44 // decrement the holders count
45 crate::furi_record_close(self.name.as_ptr());
46 }
47 }
48}