use derivative::Derivative;
use thiserror::Error;
use uuid::Uuid;
use wildland_corex::{CoreXError, ErrContext};
use wildland_dfs::{DfsFrontendError, SpaceUsage};
use super::cargo_lib::DfsApi;
#[derive(Derivative, Clone)]
#[derivative(Debug)]
pub struct ContainerStorage {
corex_storage: wildland_corex::Storage,
#[derivative(Debug = "ignore")]
dfs_api: DfsApi,
}
#[derive(Debug, Clone, Error)]
pub enum QuotaControlError {
#[error("{0}: {1}")]
CoreXError(String, CoreXError),
#[error("{0}: {1}")]
DfsFrontendError(String, DfsFrontendError),
}
impl<T> ErrContext<QuotaControlError, T> for Result<T, CoreXError> {
fn context(self, ctx: impl std::fmt::Display) -> Result<T, QuotaControlError> {
self.map_err(|e| QuotaControlError::CoreXError(ctx.to_string(), e))
}
}
impl<T> ErrContext<QuotaControlError, T> for Result<T, DfsFrontendError> {
fn context(self, ctx: impl std::fmt::Display) -> Result<T, QuotaControlError> {
self.map_err(|e| QuotaControlError::DfsFrontendError(ctx.to_string(), e))
}
}
impl ContainerStorage {
pub fn from_corex_storage(corex_storage: wildland_corex::Storage, dfs_api: DfsApi) -> Self {
Self {
corex_storage,
dfs_api,
}
}
pub fn get_space_usage(&self) -> Result<SpaceUsage, QuotaControlError> {
self.dfs_api
.get_space_usage(&self.corex_storage)
.context(format!(
"Space usage check failed for storage: uuid: {}, type: {}",
self.corex_storage.uuid(),
self.corex_storage.backend_type()
))
}
pub fn is_accessible(&self) -> Result<bool, CoreXError> {
Ok(self
.dfs_api
.is_accessible(&self.corex_storage)
.map_err(|e| tracing::error!("Storage inaccessible: {e}"))
.unwrap_or(false))
}
pub fn uuid(&self) -> Uuid {
self.corex_storage.uuid()
}
pub fn template_uuid(&self) -> Option<Uuid> {
self.corex_storage.template_uuid()
}
pub fn data(&self) -> Vec<u8> {
serde_json::to_vec(&self.corex_storage.data()).unwrap()
}
pub fn name(&self) -> Option<String> {
self.corex_storage.name()
}
pub fn backend_type(&self) -> String {
self.corex_storage.backend_type().to_owned()
}
}