| 1 | use std::ffi::OsStr; |
| 2 | use std::marker::PhantomData; |
| 3 | |
| 4 | use ffi; |
| 5 | use util; |
| 6 | |
| 7 | /// Rust wrapper for the `udev_list_entry` struct, which provides sequential |
| 8 | /// access to an associative list of string names and values. |
| 9 | /// |
| 10 | /// Each `List<T>` is parametrized on the Rust wrapper type that owns its |
| 11 | /// underlying data. For example, `List<Hwdb>` indicates a list owned by |
| 12 | /// some open handle to the `udev` hardware database. |
| 13 | pub struct List<'a, T: 'a, E: 'a> { |
| 14 | pub(crate) entry: *mut ffi::udev_list_entry, |
| 15 | pub(crate) phantom: PhantomData<&'a (T, E)>, |
| 16 | } |
| 17 | |
| 18 | #[cfg (feature = "send" )] |
| 19 | unsafe impl<T, E> Send for List<'_, T, E> {} |
| 20 | #[cfg (feature = "sync" )] |
| 21 | unsafe impl<T, E> Sync for List<'_, T, E> {} |
| 22 | |
| 23 | pub type EntryList<'a, T> = List<'a, T, Entry<'a>>; |
| 24 | |
| 25 | impl<'a, T> Iterator for EntryList<'a, T> { |
| 26 | type Item = Entry<'a>; |
| 27 | |
| 28 | fn next(&mut self) -> Option<Entry<'a>> { |
| 29 | if self.entry.is_null() { |
| 30 | None |
| 31 | } else { |
| 32 | let name: &OsStr = |
| 33 | unsafe { util::ptr_to_os_str_unchecked(ptr:ffi::udev_list_entry_get_name(self.entry)) }; |
| 34 | let value: Option<&OsStr> = unsafe { util::ptr_to_os_str(ptr:ffi::udev_list_entry_get_value(self.entry)) }; |
| 35 | |
| 36 | self.entry = unsafe { ffi::udev_list_entry_get_next(self.entry) }; |
| 37 | |
| 38 | Some(Entry { name, value }) |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | fn size_hint(&self) -> (usize, Option<usize>) { |
| 43 | (0, None) |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | /// Rust wrapper for each entry in `List`, each of which contains a name and a value. |
| 48 | pub struct Entry<'a> { |
| 49 | pub(crate) name: &'a OsStr, |
| 50 | pub(crate) value: Option<&'a OsStr>, |
| 51 | } |
| 52 | |
| 53 | impl<'a> Entry<'a> { |
| 54 | /// Returns the entry name. |
| 55 | pub fn name(&self) -> &OsStr { |
| 56 | self.name |
| 57 | } |
| 58 | |
| 59 | /// Returns the entry value. |
| 60 | pub fn value(&self) -> &OsStr { |
| 61 | self.value.unwrap_or_else(|| OsStr::new("" )) |
| 62 | } |
| 63 | } |
| 64 | |