ecr-core 0.2.1

Wire types shared by the ecr mail server and its clients
Documentation
use serde::{Deserialize, Serialize};
use std::fmt;

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Revision {
    pub uuid: String,
    pub lastmod: u64,
}

impl Revision {
    pub fn new(uuid: impl Into<String>, lastmod: u64) -> Self {
        Self {
            uuid: uuid.into(),
            lastmod,
        }
    }

    pub fn etag(&self) -> String {
        format!("\"{}-{}\"", self.uuid, self.lastmod)
    }

    pub fn supersedes(&self, other: &Revision) -> bool {
        self.uuid != other.uuid || self.lastmod > other.lastmod
    }
}

impl fmt::Display for Revision {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}:{}", self.uuid, self.lastmod)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn etag_is_quoted() {
        let rev = Revision::new("abc", 42);
        assert_eq!(rev.etag(), "\"abc-42\"");
    }

    #[test]
    fn newer_lastmod_supersedes() {
        let old = Revision::new("abc", 41);
        let new = Revision::new("abc", 42);
        assert!(new.supersedes(&old));
        assert!(!old.supersedes(&new));
    }

    #[test]
    fn different_database_always_supersedes() {
        let a = Revision::new("abc", 100);
        let b = Revision::new("xyz", 1);
        assert!(b.supersedes(&a));
    }
}