use std::sync::Arc;
use samod_core::{PeerId, ShareConfig};
use crate::{
Repo,
observer::RepoObserver,
runtime::{LocalRuntimeHandle, RuntimeHandle},
share_policy::{LocalSharePolicy, SharePolicy},
storage::{InMemoryStorage, LocalStorage, Storage},
};
pub enum ConcurrencyConfig {
AsyncRuntime,
#[cfg(feature = "threadpool")]
Threadpool(rayon::ThreadPool),
}
pub struct RepoBuilder<S, R, A> {
pub(crate) storage: S,
pub(crate) runtime: R,
pub(crate) share_policy: A,
pub(crate) peer_id: Option<PeerId>,
pub(crate) concurrency: ConcurrencyConfig,
pub(crate) observer: Option<Arc<dyn RepoObserver>>,
}
impl<S, R, A> RepoBuilder<S, R, A> {
pub fn with_storage<S2>(self, storage: S2) -> RepoBuilder<S2, R, A> {
RepoBuilder {
storage,
peer_id: self.peer_id,
runtime: self.runtime,
share_policy: self.share_policy,
concurrency: self.concurrency,
observer: self.observer,
}
}
pub fn with_runtime<R2>(self, runtime: R2) -> RepoBuilder<S, R2, A> {
RepoBuilder {
runtime,
peer_id: self.peer_id,
storage: self.storage,
share_policy: self.share_policy,
concurrency: self.concurrency,
observer: self.observer,
}
}
pub fn with_peer_id(mut self, peer_id: PeerId) -> Self {
self.peer_id = Some(peer_id);
self
}
pub fn with_share_policy<A2>(self, share_policy: A2) -> RepoBuilder<S, R, A2> {
RepoBuilder {
runtime: self.runtime,
peer_id: self.peer_id,
storage: self.storage,
share_policy,
concurrency: self.concurrency,
observer: self.observer,
}
}
pub fn with_concurrency(mut self, concurrency: ConcurrencyConfig) -> Self {
self.concurrency = concurrency;
self
}
pub fn with_observer(mut self, observer: impl RepoObserver) -> Self {
self.observer = Some(Arc::new(observer));
self
}
}
impl<R> RepoBuilder<InMemoryStorage, R, ShareConfig> {
pub fn new(runtime: R) -> RepoBuilder<InMemoryStorage, R, ShareConfig> {
RepoBuilder {
storage: InMemoryStorage::new(),
runtime,
peer_id: None,
share_policy: ShareConfig::default(),
concurrency: ConcurrencyConfig::AsyncRuntime,
observer: None,
}
}
}
impl<S: Storage, R: RuntimeHandle + Clone + Send, A: SharePolicy> RepoBuilder<S, R, A> {
pub async fn load(self) -> Repo {
Repo::load(self).await
}
}
impl<S: LocalStorage, R: LocalRuntimeHandle + Clone + 'static, A: LocalSharePolicy>
RepoBuilder<S, R, A>
{
pub async fn load_local(self) -> Repo {
Repo::load_local(self).await
}
}