use std::fmt::{self, Debug};
use monoutils_store::{ipld::cid::Cid, IpldStore, Storable, StoreError, StoreResult};
use crate::filesystem::{Dir, File, FsError, FsResult, Metadata, SoftLink};
#[derive(Clone)]
pub enum Entity<S>
where
S: IpldStore,
{
File(File<S>),
Dir(Dir<S>),
SoftLink(SoftLink<S>),
}
impl<S> Entity<S>
where
S: IpldStore,
{
pub fn is_file(&self) -> bool {
matches!(self, Entity::File(_))
}
pub fn is_dir(&self) -> bool {
matches!(self, Entity::Dir(_))
}
pub fn into_file(self) -> FsResult<File<S>> {
if let Entity::File(file) = self {
return Ok(file);
}
Err(FsError::NotAFile(String::new()))
}
pub fn into_dir(self) -> FsResult<Dir<S>> {
if let Entity::Dir(dir) = self {
return Ok(dir);
}
Err(FsError::NotADirectory(String::new()))
}
pub fn into_softlink(self) -> FsResult<SoftLink<S>> {
if let Entity::SoftLink(softlink) = self {
return Ok(softlink);
}
Err(FsError::NotASoftLink(String::new()))
}
pub fn get_metadata(&self) -> &Metadata {
match self {
Entity::File(file) => file.get_metadata(),
Entity::Dir(dir) => dir.get_metadata(),
Entity::SoftLink(softlink) => softlink.get_metadata(),
}
}
pub fn get_initial_load_cid(&self) -> Option<&Cid> {
match self {
Entity::File(file) => file.get_initial_load_cid(),
Entity::Dir(dir) => dir.get_initial_load_cid(),
Entity::SoftLink(softlink) => softlink.get_initial_load_cid(),
}
}
pub fn get_previous(&self) -> Option<&Cid> {
match self {
Entity::File(file) => file.get_previous(),
Entity::Dir(dir) => dir.get_previous(),
Entity::SoftLink(softlink) => softlink.get_previous(),
}
}
pub fn get_store(&self) -> &S {
match self {
Entity::File(file) => file.get_store(),
Entity::Dir(dir) => dir.get_store(),
Entity::SoftLink(softlink) => softlink.get_store(),
}
}
}
impl<S> Storable<S> for Entity<S>
where
S: IpldStore + Send + Sync,
{
async fn store(&self) -> StoreResult<Cid> {
match self {
Entity::File(file) => file.store().await,
Entity::Dir(dir) => dir.store().await,
Entity::SoftLink(softlink) => softlink.store().await,
}
}
async fn load(cid: &Cid, store: S) -> StoreResult<Self> {
if let Ok(softlink) = SoftLink::load(cid, store.clone()).await {
return Ok(Entity::SoftLink(softlink));
}
if let Ok(dir) = Dir::load(cid, store.clone()).await {
return Ok(Entity::Dir(dir));
}
if let Ok(file) = File::load(cid, store.clone()).await {
return Ok(Entity::File(file));
}
Err(StoreError::custom(FsError::UnableToLoadEntity(*cid)))
}
}
impl<S> Debug for Entity<S>
where
S: IpldStore,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Entity::File(file) => f.debug_tuple("File").field(file).finish(),
Entity::Dir(dir) => f.debug_tuple("Dir").field(dir).finish(),
Entity::SoftLink(softlink) => f.debug_tuple("SoftLink").field(softlink).finish(),
}
}
}