use std::{ffi, ptr}; #[derive(Default)] pub(crate) struct ListEntry { pub(crate) next: Option>, pub(crate) name: ffi::CString, pub(crate) value: Option, } impl ListEntry { pub fn add_entry(&mut self, name: ffi::CString, value: Option) -> &mut ListEntry { let new_entry = ListEntry { next: self.next.take(), name, value, }; self.next = Some(Box::new(new_entry)); self.next.as_deref_mut().unwrap() } } #[allow(non_camel_case_types)] #[repr(C)] pub struct udev_list_entry { _private: [u8; 0], } #[unsafe(no_mangle)] pub extern "C" fn udev_list_entry_init(_list_entry: *mut udev_list_entry) {} #[unsafe(no_mangle)] pub extern "C" fn udev_list_entry_free(_list_entry: *mut udev_list_entry) {} #[unsafe(no_mangle)] pub extern "C" fn udev_list_entry_free_all(_list_entry: *mut udev_list_entry) {} #[unsafe(no_mangle)] pub extern "C" fn udev_list_entry_add( _list_entry: *mut udev_list_entry, _name: *const ffi::c_char, _value: *const ffi::c_char, _uniq: ffi::c_int, ) -> *mut udev_list_entry { ptr::null_mut() } #[unsafe(no_mangle)] pub extern "C" fn udev_list_entry_get_next( list_entry: *mut udev_list_entry, ) -> *mut udev_list_entry { let Some(list_entry) = (unsafe { list_entry.cast::().as_ref() }) else { return ptr::null_mut(); }; list_entry.next.as_deref().map_or(ptr::null_mut(), |next| { ptr::from_ref(next).cast_mut().cast::() }) } #[unsafe(no_mangle)] pub extern "C" fn udev_list_entry_get_by_name( entry: *mut udev_list_entry, name: *const ffi::c_char, ) -> *mut udev_list_entry { if entry.is_null() || name.is_null() { return ptr::null_mut(); } let name = unsafe { ffi::CStr::from_ptr(name) }; let mut current = entry.cast::(); while let Some(current_entry) = unsafe { current.as_ref() } { if current_entry.name.as_c_str() == name { return current.cast::(); } current = current_entry .next .as_deref() .map_or(ptr::null_mut(), |next| ptr::from_ref(next).cast_mut()); } ptr::null_mut() } #[unsafe(no_mangle)] pub extern "C" fn udev_list_entry_get_name(list_entry: *mut udev_list_entry) -> *const ffi::c_char { let Some(list_entry) = (unsafe { list_entry.cast::().as_ref() }) else { return ptr::null(); }; list_entry.name.as_ptr() } #[unsafe(no_mangle)] pub extern "C" fn udev_list_entry_get_value( list_entry: *mut udev_list_entry, ) -> *const ffi::c_char { let Some(list_entry) = (unsafe { list_entry.cast::().as_ref() }) else { return ptr::null(); }; list_entry .value .as_ref() .map_or(ptr::null(), |value| value.as_ptr()) }