coven_format/
snapshot_stream.rs1use crate::chunks::FrameDecoder;
4use crate::error::Error;
5use crate::sealed_snapshot::SnapshotObjectPrefix;
6use crate::snapshot::{SnapshotDecoder, SnapshotHeader, SnapshotRecord, WriteSlots};
7
8pub struct SnapshotChunkDecoder {
12 prefix: SnapshotObjectPrefix,
13 frames: FrameDecoder,
14 snapshot: Option<SnapshotDecoder>,
15 frame: Vec<u8>,
16}
17impl SnapshotChunkDecoder {
18 pub fn new(prefix: SnapshotObjectPrefix) -> Self {
20 Self { prefix, frames: FrameDecoder::new(None), snapshot: None, frame: Vec::new() }
21 }
22
23 pub fn header(&self) -> Option<&SnapshotHeader> {
25 self.snapshot.as_ref().map(SnapshotDecoder::header)
26 }
27
28 pub fn next_record<O: WriteSlots>(
32 &mut self,
33 bytes: &mut &[u8],
34 oracle: &O,
35 ) -> Result<Option<SnapshotRecord>, O::Error>
36 where
37 O::Error: From<Error>,
38 {
39 while let Some(frame) = self.frames.next(bytes)? {
40 if let Some(snapshot) = &mut self.snapshot {
41 if let Some(record) = snapshot.frame(&frame, oracle)? {
42 self.frame = frame;
43 return Ok(Some(record));
44 }
45 } else {
46 let snapshot = SnapshotDecoder::start(&frame, &self.prefix)?;
47 self.snapshot = Some(snapshot);
48 }
49 }
50 Ok(None)
51 }
52
53 pub fn next_history(&mut self, bytes: &mut &[u8]) -> Result<Option<SnapshotRecord>, Error> {
58 while let Some(frame) = self.frames.next(bytes)? {
59 if let Some(snapshot) = &mut self.snapshot {
60 if let Some(record) = snapshot.history_frame(&frame)? {
61 return Ok(Some(record));
62 }
63 } else {
64 self.snapshot = Some(SnapshotDecoder::start(&frame, &self.prefix)?);
65 }
66 }
67 Ok(None)
68 }
69
70 pub fn frame(&self) -> &[u8] {
74 &self.frame
75 }
76
77 pub fn finish(&self) -> Result<(), Error> {
79 self.frames.finish()?;
80 self.snapshot.as_ref().ok_or(Error::Truncated)?.finish()
81 }
82}
83
84#[cfg(test)]
85#[path = "snapshot_stream_tests.rs"]
86mod tests;