1use std::{
6 ffi::{CStr, CString},
7 fs::File,
8 os::unix::io::AsRawFd,
9 path::PathBuf,
10 ptr,
11};
12
13use crate::{err::Result, tag::BlkidTagIter};
14
15pub struct BlkidSize(libblkid_rs_sys::blkid_loff_t);
17
18impl Into<i64> for BlkidSize {
19 fn into(self) -> i64 {
20 self.0
21 }
22}
23
24pub struct BlkidDev(libblkid_rs_sys::blkid_dev);
26
27impl BlkidDev {
28 pub(crate) fn new(inner: libblkid_rs_sys::blkid_dev) -> Self {
29 BlkidDev(inner)
30 }
31
32 pub(crate) fn as_ptr(&self) -> libblkid_rs_sys::blkid_dev {
33 self.0
34 }
35
36 pub fn devname(&self) -> Result<PathBuf> {
38 let ret = errno_ptr!(unsafe { libblkid_rs_sys::blkid_dev_devname(self.0) })?;
39 let cstr_ret = unsafe { CStr::from_ptr(ret) };
40 Ok(PathBuf::from(cstr_ret.to_str()?))
41 }
42
43 pub fn devsize(&self) -> Result<BlkidSize> {
45 let f = File::open(self.devname()?)?;
46 Ok(BlkidSize(unsafe {
47 libblkid_rs_sys::blkid_get_dev_size(f.as_raw_fd())
48 }))
49 }
50
51 pub fn tag_iter(&self) -> BlkidTagIter {
53 BlkidTagIter::new(unsafe { libblkid_rs_sys::blkid_tag_iterate_begin(self.0) })
54 }
55
56 pub fn has_tag(&self, type_: &str, value: &str) -> Result<bool> {
58 let type_cstring = CString::new(type_)?;
59 let value_cstring = CString::new(value)?;
60 Ok(unsafe {
61 libblkid_rs_sys::blkid_dev_has_tag(
62 self.0,
63 type_cstring.as_ptr(),
64 value_cstring.as_ptr(),
65 )
66 } != 0)
67 }
68}
69
70pub struct BlkidDevIter(libblkid_rs_sys::blkid_dev_iterate);
72
73impl BlkidDevIter {
74 pub(crate) fn new(iter: libblkid_rs_sys::blkid_dev_iterate) -> Self {
75 BlkidDevIter(iter)
76 }
77
78 pub fn search(self, search_type: &str, search_value: &str) -> Result<Self> {
80 let search_type_cstring = CString::new(search_type)?;
81 let search_value_cstring = CString::new(search_value)?;
82 errno!(unsafe {
83 libblkid_rs_sys::blkid_dev_set_search(
84 self.0,
85 search_type_cstring.as_ptr() as *mut _,
86 search_value_cstring.as_ptr() as *mut _,
87 )
88 })?;
89 Ok(self)
90 }
91}
92
93impl Iterator for BlkidDevIter {
94 type Item = BlkidDev;
95
96 fn next(&mut self) -> Option<Self::Item> {
97 let mut dev: libblkid_rs_sys::blkid_dev = ptr::null_mut();
98 if unsafe { libblkid_rs_sys::blkid_dev_next(self.0, &mut dev as *mut _) } < 0 {
99 None
100 } else {
101 assert!(!dev.is_null());
102 Some(BlkidDev(dev))
103 }
104 }
105}
106
107impl Drop for BlkidDevIter {
108 fn drop(&mut self) {
109 unsafe { libblkid_rs_sys::blkid_dev_iterate_end(self.0) }
110 }
111}