use std::mem::MaybeUninit;
use crate::core::partition::PartitionTableType;
use crate::ffi_utils;
use crate::probe::{Partition, Probe};
#[derive(Debug)]
pub struct PartitionTable<'a> {
pub(super) ptr: libblkid::blkid_parttable,
marker: &'a Probe,
}
impl<'a> PartitionTable<'a> {
#[doc(hidden)]
pub(super) fn new(marker: &'a Probe, table: libblkid::blkid_parttable) -> PartitionTable<'a> {
log::debug!("PartitionTable::new creating a new `PartitionTable` instance");
Self { ptr: table, marker }
}
pub fn id(&self) -> Option<String> {
log::debug!("PartitionTable::id getting a partition table's ID");
let mut ptr = MaybeUninit::<*const libc::c_char>::zeroed();
unsafe {
ptr.write(libblkid::blkid_parttable_get_id(self.ptr));
}
match unsafe { ptr.assume_init() } {
id_ptr if id_ptr.is_null() => {
log::debug!("PartitionTable::id failed to get partition table's ID. libblkid::blkid_parttable_get_id returned a NULL pointer");
None
}
id_ptr => {
let hex_id = ffi_utils::c_char_array_to_string(id_ptr);
log::debug!("PartitionTable::id partition table ID: {:?}", hex_id);
Some(hex_id)
}
}
}
pub fn location_in_bytes(&self) -> Option<u64> {
log::debug!("PartitionTable::location_in_bytes getting partition table's location");
let result = unsafe { libblkid::blkid_parttable_get_offset(self.ptr) };
match result {
location if location >= 0 => {
let location = location as u64;
log::debug!(
"PartitionTable::location_in_bytes partition table's location: {:?}",
location
);
Some(location)
}
code => {
let err_msg = "failed to get partition table's location on device".to_owned();
log::debug!("PartitionTable::location_in_bytes {}. libblkid::blkid_parttable_get_offset returned error code {:?}",err_msg, code);
None
}
}
}
pub fn parent(&self) -> Option<Partition> {
log::debug!("PartitionTable::parent getting a partition table's parent partition");
unsafe {
let mut ptr = MaybeUninit::<libblkid::blkid_partition>::zeroed();
ptr.write(libblkid::blkid_parttable_get_parent(self.ptr));
match ptr.assume_init() {
partition if partition.is_null() => {
log::debug!("PartitionTable::parent failed to get partition table's parent partition. libblkid::blkid_parttable_get_parent returned a NULL pointer");
None
}
partition => {
log::debug!("PartitionTable::parent got partition table's parent partition");
Some(Partition::new(self.marker, partition))
}
}
}
}
pub fn partition_table_type(&self) -> Option<PartitionTableType> {
let mut ptr = MaybeUninit::<*const libc::c_char>::zeroed();
unsafe {
ptr.write(libblkid::blkid_parttable_get_type(self.ptr));
}
let ptr = unsafe { ptr.assume_init() };
let pt_type = ffi_utils::const_c_char_array_to_bytes(ptr);
let table_type = PartitionTableType::try_from(pt_type).ok();
log::debug!(
"PartitionTable::partition_table_type partition table's type: {:?}",
table_type
);
table_type
}
}
impl<'a> PartialEq for PartitionTable<'a> {
fn eq(&self, other: &Self) -> bool {
self.id() == other.id()
}
}
impl<'a> Eq for PartitionTable<'a> {}