use anyhow::{Context, anyhow};
use async_trait::async_trait;
use std::path::PathBuf;
use thiserror::Error;
use mithril_common::entities::ImmutableFileNumber;
use mithril_common::{StdError, StdResult};
use crate::entities::ImmutableFile;
#[async_trait]
pub trait ImmutableFileObserver
where
Self: Sync + Send,
{
async fn get_last_immutable_number(&self) -> StdResult<ImmutableFileNumber>;
}
#[derive(Error, Debug)]
pub enum ImmutableFileObserverError {
#[error("no immutable file was returned")]
Missing(),
#[error("immutable file creation error")]
ImmutableFileListing(#[source] StdError),
}
pub struct ImmutableFileSystemObserver {
db_path: PathBuf,
}
impl ImmutableFileSystemObserver {
pub fn new(db_path: &PathBuf) -> Self {
let db_path = db_path.to_owned();
Self { db_path }
}
}
#[async_trait]
impl ImmutableFileObserver for ImmutableFileSystemObserver {
async fn get_last_immutable_number(&self) -> StdResult<u64> {
let immutable_file_number = ImmutableFile::list_completed_in_dir(&self.db_path)
.with_context(|| "Immutable File System Observer can not list all immutable files")?
.into_iter()
.next_back()
.ok_or(anyhow!(ImmutableFileObserverError::Missing()))?
.number;
Ok(immutable_file_number)
}
}