use crate::{
commit::{CommitHash, CommitProof},
events::{AccountEvent, DeviceEvent, EventRecord, WriteEvent},
Result,
};
use binary_stream::futures::{Decodable, Encodable};
use std::marker::PhantomData;
#[cfg(feature = "files")]
use crate::events::FileEvent;
pub type AccountPatch = Patch<AccountEvent>;
pub type FolderPatch = Patch<WriteEvent>;
pub type DevicePatch = Patch<DeviceEvent>;
#[cfg(feature = "files")]
pub type FilePatch = Patch<FileEvent>;
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Patch<T>(Vec<EventRecord>, PhantomData<T>);
impl<T> Patch<T> {
pub fn new(records: Vec<EventRecord>) -> Self {
Self(records, PhantomData)
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn iter(&self) -> impl Iterator<Item = &EventRecord> {
self.0.iter()
}
pub fn records(&self) -> &[EventRecord] {
self.0.as_slice()
}
pub async fn into_events<E: Default + Decodable + Encodable>(
&self,
) -> Result<Vec<E>> {
let mut events = Vec::with_capacity(self.0.len());
for record in &self.0 {
events.push(record.decode_event::<E>().await?);
}
Ok(events)
}
}
impl<T> From<Patch<T>> for Vec<EventRecord> {
fn from(value: Patch<T>) -> Self {
value.0
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CheckedPatch {
Success(CommitProof),
Conflict {
head: CommitProof,
contains: Option<CommitProof>,
},
}
#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct Diff<T> {
pub patch: Patch<T>,
pub checkpoint: CommitProof,
pub last_commit: Option<CommitHash>,
}
impl<T> Diff<T> {
pub fn new(
patch: Patch<T>,
checkpoint: CommitProof,
last_commit: Option<CommitHash>,
) -> Self {
Self {
patch,
checkpoint,
last_commit,
}
}
}
pub type AccountDiff = Diff<AccountEvent>;
pub type DeviceDiff = Diff<DeviceEvent>;
#[cfg(feature = "files")]
pub type FileDiff = Diff<FileEvent>;
pub type FolderDiff = Diff<WriteEvent>;