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 | pub type EntryList<'a, T> = List<'a, T, Entry<'a>>; |
18 | |
19 | impl<'a, T> Iterator for EntryList<'a, T> { |
20 | type Item = Entry<'a>; |
21 | |
22 | fn next(&mut self) -> Option<Entry<'a>> { |
23 | if self.entry.is_null() { |
24 | None |
25 | } else { |
26 | let name: &OsStr = |
27 | unsafe { util::ptr_to_os_str_unchecked(ptr:ffi::udev_list_entry_get_name(self.entry)) }; |
28 | let value: Option<&OsStr> = unsafe { util::ptr_to_os_str(ptr:ffi::udev_list_entry_get_value(self.entry)) }; |
29 | |
30 | self.entry = unsafe { ffi::udev_list_entry_get_next(self.entry) }; |
31 | |
32 | Some(Entry { name, value }) |
33 | } |
34 | } |
35 | |
36 | fn size_hint(&self) -> (usize, Option<usize>) { |
37 | (0, None) |
38 | } |
39 | } |
40 | |
41 | /// Rust wrapper for each entry in `List`, each of which contains a name and a value. |
42 | pub struct Entry<'a> { |
43 | pub(crate) name: &'a OsStr, |
44 | pub(crate) value: Option<&'a OsStr>, |
45 | } |
46 | |
47 | impl<'a> Entry<'a> { |
48 | /// Returns the entry name. |
49 | pub fn name(&self) -> &OsStr { |
50 | self.name |
51 | } |
52 | |
53 | /// Returns the entry value. |
54 | pub fn value(&self) -> &OsStr { |
55 | self.value.unwrap_or_else(|| OsStr::new("" )) |
56 | } |
57 | } |
58 | |