Skip to main content

libblkid_rs/
tag.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5use std::{
6    ffi::{CStr, CString},
7    ptr,
8};
9
10use libc::c_char;
11
12use crate::{err::BlkidErr, Result};
13
14/// Iterator for tags associated with a device
15pub struct BlkidTagIter(libblkid_rs_sys::blkid_tag_iterate);
16
17impl BlkidTagIter {
18    pub(crate) fn new(iter: libblkid_rs_sys::blkid_tag_iterate) -> Self {
19        BlkidTagIter(iter)
20    }
21}
22
23impl Iterator for BlkidTagIter {
24    type Item = (String, String);
25
26    fn next(&mut self) -> Option<Self::Item> {
27        let mut type_: *const c_char = ptr::null_mut();
28        let mut value: *const c_char = ptr::null_mut();
29        if unsafe {
30            libblkid_rs_sys::blkid_tag_next(
31                self.0,
32                &mut type_ as *mut *const _,
33                &mut value as *mut *const _,
34            )
35        } < 0
36        {
37            None
38        } else {
39            assert!(!type_.is_null() && !value.is_null());
40            let type_str = unsafe { CStr::from_ptr(type_) };
41            let value_str = unsafe { CStr::from_ptr(value) };
42            Some((
43                type_str.to_str().ok()?.to_string(),
44                value_str.to_str().ok()?.to_string(),
45            ))
46        }
47    }
48}
49
50impl Drop for BlkidTagIter {
51    fn drop(&mut self) {
52        unsafe { libblkid_rs_sys::blkid_tag_iterate_end(self.0) }
53    }
54}
55
56/// Parse a tag string into a tuple of type and value
57pub fn parse_tag_string(tag_string: &str) -> Result<(String, String)> {
58    let tag_cstring = CString::new(tag_string)?;
59    let mut type_: *mut c_char = ptr::null_mut();
60    let mut value: *mut c_char = ptr::null_mut();
61    let ret = unsafe {
62        libblkid_rs_sys::blkid_parse_tag_string(
63            tag_cstring.as_ptr(),
64            &mut type_ as *mut *mut _,
65            &mut value as *mut *mut _,
66        )
67    };
68    if ret < 0 {
69        Err(BlkidErr::LibErr(i64::from(ret)))
70    } else {
71        assert!(!type_.is_null() && !value.is_null());
72        let type_str = unsafe { CStr::from_ptr(type_) };
73        let value_str = unsafe { CStr::from_ptr(value) };
74        Ok((
75            type_str.to_str()?.to_string(),
76            value_str.to_str()?.to_string(),
77        ))
78    }
79}