Skip to main content

ecr_core/
revision.rs

1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5pub struct Revision {
6    pub uuid: String,
7    pub lastmod: u64,
8}
9
10impl Revision {
11    pub fn new(uuid: impl Into<String>, lastmod: u64) -> Self {
12        Self {
13            uuid: uuid.into(),
14            lastmod,
15        }
16    }
17
18    pub fn etag(&self) -> String {
19        format!("\"{}-{}\"", self.uuid, self.lastmod)
20    }
21
22    pub fn supersedes(&self, other: &Revision) -> bool {
23        self.uuid != other.uuid || self.lastmod > other.lastmod
24    }
25}
26
27impl fmt::Display for Revision {
28    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29        write!(f, "{}:{}", self.uuid, self.lastmod)
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use super::*;
36
37    #[test]
38    fn etag_is_quoted() {
39        let rev = Revision::new("abc", 42);
40        assert_eq!(rev.etag(), "\"abc-42\"");
41    }
42
43    #[test]
44    fn newer_lastmod_supersedes() {
45        let old = Revision::new("abc", 41);
46        let new = Revision::new("abc", 42);
47        assert!(new.supersedes(&old));
48        assert!(!old.supersedes(&new));
49    }
50
51    #[test]
52    fn different_database_always_supersedes() {
53        let a = Revision::new("abc", 100);
54        let b = Revision::new("xyz", 1);
55        assert!(b.supersedes(&a));
56    }
57}