pamoja_core/store.rs
1//! Durable local storage backing the offline-first synchronization layer.
2
3use alloc::vec::Vec;
4
5use crate::error::Result;
6
7/// A durable, first-in first-out queue for store-and-forward buffering.
8///
9/// Records are appended while a device is offline and drained in order when a
10/// link becomes available, letting applications tolerate intermittent
11/// connectivity without losing data.
12pub trait Store {
13 /// Appends a record to the back of the queue.
14 ///
15 /// # Arguments
16 ///
17 /// * `record` - the raw bytes to persist.
18 ///
19 /// # Returns
20 ///
21 /// `Ok(())` once the record is durably stored.
22 ///
23 /// # Errors
24 ///
25 /// Returns [`Error::Io`](crate::Error::Io) if the record cannot be written to
26 /// durable storage.
27 async fn append(&mut self, record: &[u8]) -> Result<()>;
28
29 /// Returns the oldest record without removing it.
30 ///
31 /// This lets a forwarder send a record before committing to its removal, so a
32 /// failed send can leave the record buffered in order rather than dropping it.
33 ///
34 /// # Returns
35 ///
36 /// `Some(record)` containing the oldest buffered bytes, or `None` if the queue
37 /// is empty.
38 ///
39 /// # Errors
40 ///
41 /// Returns [`Error::Io`](crate::Error::Io) if the queue cannot be read.
42 async fn peek(&self) -> Result<Option<Vec<u8>>>;
43
44 /// Removes and returns the oldest record in the queue.
45 ///
46 /// # Returns
47 ///
48 /// `Some(record)` containing the oldest buffered bytes, or `None` if the queue
49 /// is empty.
50 ///
51 /// # Errors
52 ///
53 /// Returns [`Error::Io`](crate::Error::Io) if the queue cannot be read.
54 async fn pop(&mut self) -> Result<Option<Vec<u8>>>;
55
56 /// Returns the number of records currently buffered.
57 ///
58 /// # Returns
59 ///
60 /// The count of records waiting to be drained.
61 ///
62 /// # Errors
63 ///
64 /// Returns [`Error::Io`](crate::Error::Io) if the queue length cannot be
65 /// determined.
66 async fn len(&self) -> Result<usize>;
67
68 /// Returns whether the queue currently holds no records.
69 ///
70 /// The default implementation reports whether [`len`](Self::len) is zero.
71 ///
72 /// # Returns
73 ///
74 /// `true` if the queue is empty, `false` otherwise.
75 ///
76 /// # Errors
77 ///
78 /// Returns [`Error::Io`](crate::Error::Io) if the queue length cannot be
79 /// determined.
80 async fn is_empty(&self) -> Result<bool> {
81 Ok(self.len().await? == 0)
82 }
83}