1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//! Patch represents a changeset of events to apply to a vault.
use crate::{
    constants::PATCH_IDENTITY, encoding::encoding_error, events::EventRecord,
    formats::FileIdentity, patch::Patch,
};

use async_trait::async_trait;
use binary_stream::futures::{
    BinaryReader, BinaryWriter, Decodable, Encodable,
};
use futures::io::{AsyncRead, AsyncSeek, AsyncWrite};
use std::io::Result;

#[async_trait]
impl Encodable for Patch {
    async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
        &self,
        writer: &mut BinaryWriter<W>,
    ) -> Result<()> {
        writer.write_bytes(PATCH_IDENTITY).await?;
        for event in self.0.iter() {
            event.encode(writer).await?;
        }
        Ok(())
    }
}

#[async_trait]
impl Decodable for Patch {
    async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
        &mut self,
        reader: &mut BinaryReader<R>,
    ) -> Result<()> {
        FileIdentity::read_identity(reader, &PATCH_IDENTITY)
            .await
            .map_err(encoding_error)?;
        let mut pos = reader.stream_position().await?;
        let len = reader.len().await?;
        while pos < len {
            let mut event: EventRecord = Default::default();
            event.decode(reader).await?;
            self.0.push(event);
            pos = reader.stream_position().await?;
        }
        Ok(())
    }
}