use std::pin::Pin;
use futures::{Future, Stream};
use thiserror::Error;
use crate::StorageBackend;
pub(crate) trait Telepathic {
type ID: Clone + PartialEq + Eq + std::hash::Hash;
type WriteAccess;
type StateInfo: PartialEq + Eq;
type Diff: TelepathicDiff<ID = Self::ID>;
type Error;
fn id(&self) -> Self::ID;
fn try_apply_diff(
&mut self,
diff: Self::Diff,
) -> ApplyDiffResult<Self::StateInfo, Self::ID, Self::Diff, Self::Error>;
fn state_info(&self) -> Option<Self::StateInfo>;
fn diff_since(&self, state_info: Option<&Self::StateInfo>) -> Option<Self::Diff>;
fn state_as_initial_diff(&self) -> Option<Self::Diff> {
self.diff_since(None)
}
fn load(
id: Self::ID,
storage: Box<dyn StorageBackend>,
) -> Pin<Box<dyn Stream<Item = Self::Diff>>>;
fn store(
effective_diff: Self::Diff,
storage: Box<dyn StorageBackend>,
) -> Pin<Box<dyn Future<Output = ()>>>;
}
pub struct ApplyDiffSuccess<
S: PartialEq + Eq,
ID: Clone + PartialEq + Eq + std::hash::Hash,
D: TelepathicDiff<ID = ID>,
> {
pub new_state_info: S,
pub effective_diff: D,
}
pub type ApplyDiffResult<S, ID, D, E> = Result<ApplyDiffSuccess<S, ID, D>, ApplyDiffErrorFor<E>>;
pub trait TelepathicDiff {
type ID: Clone + PartialEq + Eq + std::hash::Hash;
fn id(&self) -> Self::ID;
}
#[derive(Debug, Error)]
pub enum ApplyDiffErrorFor<E> {
#[error("Invalid known state assumed")]
InvalidKnownStateAssumption,
#[error(transparent)]
Other(#[from] E),
}