use crate::Expirable;
#[cfg(doc)]
use crate::SeqMarked;
pub trait SeqValue<M, V = Vec<u8>> {
fn seq(&self) -> u64;
fn value(&self) -> Option<&V>;
fn into_value(self) -> Option<V>;
fn meta(&self) -> Option<&M>;
fn unpack(self) -> (u64, Option<V>)
where Self: Sized {
(self.seq(), self.into_value())
}
fn expires_at_ms_opt(&self) -> Option<u64>
where M: Expirable {
let meta = self.meta()?;
meta.expires_at_ms_opt()
}
fn expires_at_ms(&self) -> u64
where M: Expirable {
self.meta().expires_at_ms()
}
fn is_expired(&self, now_ms: u64) -> bool
where M: Expirable {
self.expires_at_ms() < now_ms
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::testing::*;
#[test]
fn test_seq_value_basic() {
let sv = SeqValueImpl {
seq: 42,
value: Some(100),
meta: None,
};
assert_eq!(sv.seq(), 42);
assert_eq!(sv.value(), Some(&100));
assert_eq!(sv.meta(), None);
let (seq, value) = sv.unpack();
assert_eq!(seq, 42);
assert_eq!(value, Some(100));
}
#[test]
fn test_seq_value_with_expiration() {
let sv = SeqValueImpl {
seq: 1,
value: Some(200),
meta: Some(ExpirableImpl {
expires_at_ms: Some(1000),
}),
};
assert_eq!(sv.expires_at_ms_opt(), Some(1000));
assert_eq!(sv.expires_at_ms(), 1000);
assert!(sv.is_expired(1001));
assert!(!sv.is_expired(999));
}
#[test]
fn test_seq_value_no_expiration() {
let sv = SeqValueImpl {
seq: 2,
value: None,
meta: Some(ExpirableImpl {
expires_at_ms: None,
}),
};
assert_eq!(sv.expires_at_ms_opt(), None);
assert_eq!(sv.expires_at_ms(), u64::MAX);
assert!(!sv.is_expired(u64::MAX - 1));
}
}