diff options
Diffstat (limited to 'src/persist.rs')
| -rw-r--r-- | src/persist.rs | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/persist.rs b/src/persist.rs new file mode 100644 index 0000000..8e733b0 --- /dev/null +++ b/src/persist.rs @@ -0,0 +1,84 @@ +//! Persistence traits for data and routing table. +//! +//! The library defines the traits; applications +//! implement backends (SQLite, file, etc). + +use crate::error::Error; +use crate::id::NodeId; +use std::net::SocketAddr; + +/// Stored value record for persistence. +#[derive(Debug, Clone)] +pub struct StoredRecord { + pub key: Vec<u8>, + pub value: Vec<u8>, + pub target_id: NodeId, + pub source: NodeId, + pub ttl: u16, + pub is_unique: bool, +} + +/// Contact record for routing table persistence. +#[derive(Debug, Clone)] +pub struct ContactRecord { + pub id: NodeId, + pub addr: SocketAddr, +} + +/// Trait for persisting DHT stored values. +/// +/// Implement this to survive restarts. The library +/// calls `save` periodically and `load` on startup. +pub trait DataPersistence { + /// Save all stored values. + fn save(&self, records: &[StoredRecord]) -> Result<(), Error>; + + /// Load previously saved values. + fn load(&self) -> Result<Vec<StoredRecord>, Error>; +} + +/// Trait for persisting the routing table. +/// +/// Implement this for fast re-bootstrap after restart. +pub trait RoutingPersistence { + /// Save known contacts. + fn save_contacts(&self, contacts: &[ContactRecord]) -> Result<(), Error>; + + /// Load previously saved contacts. + fn load_contacts(&self) -> Result<Vec<ContactRecord>, Error>; +} + +/// No-op persistence (default — no persistence). +pub struct NoPersistence; + +impl DataPersistence for NoPersistence { + fn save(&self, _records: &[StoredRecord]) -> Result<(), Error> { + Ok(()) + } + fn load(&self) -> Result<Vec<StoredRecord>, Error> { + Ok(Vec::new()) + } +} + +impl RoutingPersistence for NoPersistence { + fn save_contacts(&self, _contacts: &[ContactRecord]) -> Result<(), Error> { + Ok(()) + } + fn load_contacts(&self) -> Result<Vec<ContactRecord>, Error> { + Ok(Vec::new()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn no_persistence_save_load() { + let p = NoPersistence; + assert!(p.save(&[]).is_ok()); + assert!(p.load().unwrap().is_empty()); + assert!(p.save_contacts(&[]).is_ok()); + assert!(p.load_contacts().unwrap().is_empty()); + } +} |