use chrono::SecondsFormat;
use dbus::Path;
use dbus_tree::{MTSync, Tree};
use crate::{
dbus_api::types::TData,
engine::{Filesystem, Name},
};
pub fn filesystem_operation<F, R>(
tree: &Tree<MTSync<TData>, TData>,
object_path: &Path<'static>,
closure: F,
) -> Result<R, String>
where
F: Fn((Name, Name, &dyn Filesystem)) -> Result<R, String>,
R: dbus::arg::Append,
{
let dbus_context = tree.get_data();
let filesystem_path = tree
.get(object_path)
.expect("tree must contain implicit argument");
let filesystem_data = filesystem_path
.get_data()
.as_ref()
.ok_or_else(|| format!("no data for object path {}", object_path))?;
let pool_path = tree
.get(&filesystem_data.parent)
.ok_or_else(|| format!("no path for parent object path {}", &filesystem_data.parent))?;
let pool_uuid = typed_uuid_string_err!(
pool_path
.get_data()
.as_ref()
.ok_or_else(|| format!("no data for object path {}", object_path))?
.uuid;
Pool
);
let mutex_lock = dbus_context.engine.blocking_lock();
let (pool_name, pool) = mutex_lock
.get_pool(pool_uuid)
.ok_or_else(|| format!("no pool corresponding to uuid {}", &pool_uuid))?;
let filesystem_uuid = typed_uuid_string_err!(filesystem_data.uuid; Fs);
let (fs_name, fs) = pool
.get_filesystem(filesystem_uuid)
.ok_or_else(|| format!("no name for filesystem with uuid {}", &filesystem_uuid))?;
closure((pool_name, fs_name, fs))
}
#[inline]
pub fn fs_name_prop(name: &Name) -> String {
name.to_owned()
}
#[inline]
pub fn fs_devnode_prop(fs: &dyn Filesystem, pool_name: &Name, fs_name: &Name) -> String {
fs.path_to_mount_filesystem(pool_name, fs_name)
.display()
.to_string()
}
#[inline]
pub fn fs_created_prop(fs: &dyn Filesystem) -> String {
fs.created().to_rfc3339_opts(SecondsFormat::Secs, true)
}