1use std::ffi::OsStr;
2use std::marker::PhantomData;
3
4use ffi;
5use 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.
13pub 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}
17pub type EntryList<'a, T> = List<'a, T, Entry<'a>>;
18
19impl<'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.
42pub struct Entry<'a> {
43 pub(crate) name: &'a OsStr,
44 pub(crate) value: Option<&'a OsStr>,
45}
46
47impl<'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