1use std::{future::pending, num::NonZero, path::PathBuf, sync::Arc, time::Duration};
2
3use culprit::{Result, ResultExt};
4use serde::{Deserialize, Serialize};
5use thiserror::Error;
6
7use crate::{
8 local::fjall_storage::{FjallStorage, FjallStorageErr},
9 remote::{RemoteConfig, RemoteErr},
10 rt::runtime::Runtime,
11};
12
13#[derive(Debug, Deserialize, Serialize)]
14pub struct GraftConfig {
15 pub remote: RemoteConfig,
17
18 pub data_dir: PathBuf,
20
21 #[serde(default)]
23 pub autosync: Option<NonZero<u64>>,
24}
25
26#[derive(Debug, Error)]
27pub enum InitErr {
28 #[error(transparent)]
29 IoErr(#[from] std::io::Error),
30
31 #[error(transparent)]
32 Storage(#[from] FjallStorageErr),
33
34 #[error(transparent)]
35 Remote(#[from] RemoteErr),
36}
37
38pub fn setup_graft(config: GraftConfig) -> Result<Runtime, InitErr> {
44 let rt = tokio::runtime::Builder::new_current_thread()
46 .enable_all()
47 .build()?;
48 let tokio_handle = rt.handle().clone();
49 std::thread::Builder::new()
50 .name("graft-runtime".to_string())
51 .spawn(move || {
52 rt.block_on(pending::<()>())
54 })?;
55
56 let remote = Arc::new(config.remote.build().or_into_ctx()?);
57 let storage = Arc::new(FjallStorage::open(config.data_dir).or_into_ctx()?);
58 let autosync = config.autosync.map(|s| Duration::from_secs(s.get()));
59 Ok(Runtime::new(tokio_handle, remote, storage, autosync))
60}