use crate::error::{VZError, VZResult};
use crate::shim_ffi;
use std::ffi::{CString, c_void};
use std::path::Path;
use std::ptr;
pub struct StorageDeviceConfiguration {
inner: *mut c_void,
}
unsafe impl Send for StorageDeviceConfiguration {}
impl StorageDeviceConfiguration {
pub fn disk_image(path: impl AsRef<Path>, read_only: bool) -> VZResult<Self> {
let path = path.as_ref();
if !path.exists() {
return Err(VZError::NotFound(path.display().to_string()));
}
let c_path = CString::new(path.to_string_lossy().as_bytes()).map_err(|_| {
VZError::InvalidConfiguration(format!("path contains NUL: {}", path.display()))
})?;
unsafe {
let mut error: *mut std::ffi::c_char = ptr::null_mut();
let obj =
shim_ffi::abx_storage_disk_image_new(c_path.as_ptr(), read_only, &raw mut error);
if obj.is_null() {
return Err(VZError::InvalidConfiguration(shim_ffi::take_error_string(
error,
)));
}
Ok(Self { inner: obj })
}
}
#[must_use]
pub(crate) fn into_ptr(self) -> *mut c_void {
let ptr = self.inner;
std::mem::forget(self);
ptr
}
}
impl Drop for StorageDeviceConfiguration {
fn drop(&mut self) {
if !self.inner.is_null() {
unsafe { shim_ffi::abx_object_release(self.inner.cast()) };
}
}
}