lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

checkpoint.rs (3373B)


      1 #![allow(clippy::module_name_repetitions)]
      2 #[cfg(not(feature = "std"))]
      3 use alloc::{string::String, vec::Vec};
      4 
      5 use crate::types::RadrootsEventsIndexedShardId;
      6 
      7 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
      8 #[derive(Clone, Debug, PartialEq, Eq)]
      9 pub struct RadrootsEventsIndexedShardCheckpoint {
     10     pub shard_id: RadrootsEventsIndexedShardId,
     11     #[cfg_attr(
     12         feature = "serde",
     13         serde(deserialize_with = "crate::serde_ext::epoch_seconds::de")
     14     )]
     15     pub last_created_at: u32,
     16     pub last_event_id: Option<String>,
     17     pub cursor: Option<String>,
     18 }
     19 
     20 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
     21 #[derive(Clone, Debug, PartialEq, Eq)]
     22 pub struct RadrootsEventsIndexedIndexCheckpoint {
     23     #[cfg_attr(
     24         feature = "serde",
     25         serde(deserialize_with = "crate::serde_ext::epoch_seconds::de")
     26     )]
     27     pub generated_at: u32,
     28     pub shards: Vec<RadrootsEventsIndexedShardCheckpoint>,
     29 }
     30 
     31 impl RadrootsEventsIndexedIndexCheckpoint {
     32     pub fn get(
     33         &self,
     34         id: &RadrootsEventsIndexedShardId,
     35     ) -> Option<&RadrootsEventsIndexedShardCheckpoint> {
     36         self.shards.iter().find(|s| &s.shard_id == id)
     37     }
     38     pub fn upsert(&mut self, cp: RadrootsEventsIndexedShardCheckpoint) {
     39         if let Some(slot) = self.shards.iter_mut().find(|s| s.shard_id == cp.shard_id) {
     40             *slot = cp;
     41         } else {
     42             self.shards.push(cp);
     43         }
     44     }
     45 }
     46 
     47 #[cfg(test)]
     48 mod tests {
     49     use super::{RadrootsEventsIndexedIndexCheckpoint, RadrootsEventsIndexedShardCheckpoint};
     50     use crate::types::RadrootsEventsIndexedShardId;
     51     #[cfg(not(feature = "std"))]
     52     use alloc::{string::String, vec, vec::Vec};
     53     #[cfg(feature = "std")]
     54     use std::{string::String, vec::Vec};
     55 
     56     fn checkpoint(
     57         shard_id: &str,
     58         last_created_at: u32,
     59         last_event_id: Option<&str>,
     60     ) -> RadrootsEventsIndexedShardCheckpoint {
     61         RadrootsEventsIndexedShardCheckpoint {
     62             shard_id: RadrootsEventsIndexedShardId(String::from(shard_id)),
     63             last_created_at,
     64             last_event_id: last_event_id.map(String::from),
     65             cursor: None,
     66         }
     67     }
     68 
     69     #[test]
     70     fn get_returns_none_for_unknown_shard() {
     71         let cp = RadrootsEventsIndexedIndexCheckpoint {
     72             generated_at: 1,
     73             shards: vec![checkpoint("us-1", 10, Some("a"))],
     74         };
     75         let missing = cp.get(&RadrootsEventsIndexedShardId(String::from("us-2")));
     76         assert!(missing.is_none());
     77     }
     78 
     79     #[test]
     80     fn upsert_inserts_and_updates_shards() {
     81         let mut cp = RadrootsEventsIndexedIndexCheckpoint {
     82             generated_at: 2,
     83             shards: Vec::new(),
     84         };
     85 
     86         cp.upsert(checkpoint("us-1", 10, Some("a")));
     87         assert_eq!(cp.shards.len(), 1);
     88         assert_eq!(
     89             cp.get(&RadrootsEventsIndexedShardId(String::from("us-1")))
     90                 .expect("inserted shard")
     91                 .last_created_at,
     92             10
     93         );
     94 
     95         cp.upsert(checkpoint("us-1", 11, Some("b")));
     96         assert_eq!(cp.shards.len(), 1);
     97         let updated = cp
     98             .get(&RadrootsEventsIndexedShardId(String::from("us-1")))
     99             .expect("updated shard");
    100         assert_eq!(updated.last_created_at, 11);
    101         assert_eq!(updated.last_event_id.as_deref(), Some("b"));
    102     }
    103 }