use std::{future::pending, num::NonZero, path::PathBuf, sync::Arc, time::Duration};
use culprit::{Result, ResultExt};
use serde::{Deserialize, Serialize};
use thiserror::Error;
use crate::{
local::fjall_storage::{FjallStorage, FjallStorageErr},
remote::{RemoteConfig, RemoteErr},
rt::runtime::Runtime,
};
#[derive(Debug, Deserialize, Serialize)]
pub struct GraftConfig {
pub remote: RemoteConfig,
pub data_dir: PathBuf,
#[serde(default)]
pub autosync: Option<NonZero<u64>>,
}
#[derive(Debug, Error)]
pub enum InitErr {
#[error(transparent)]
IoErr(#[from] std::io::Error),
#[error(transparent)]
Storage(#[from] FjallStorageErr),
#[error(transparent)]
Remote(#[from] RemoteErr),
}
pub fn setup_graft(config: GraftConfig) -> Result<Runtime, InitErr> {
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()?;
let tokio_handle = rt.handle().clone();
std::thread::Builder::new()
.name("graft-runtime".to_string())
.spawn(move || {
rt.block_on(pending::<()>())
})?;
let remote = Arc::new(config.remote.build().or_into_ctx()?);
let storage = Arc::new(FjallStorage::open(config.data_dir).or_into_ctx()?);
let autosync = config.autosync.map(|s| Duration::from_secs(s.get()));
Ok(Runtime::new(tokio_handle, remote, storage, autosync))
}