#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum KeyValue {
Int(i64),
Text(String),
}
impl KeyValue {
#[must_use]
pub const fn as_int(&self) -> Option<i64> {
match self {
Self::Int(v) => Some(*v),
Self::Text(_) => None,
}
}
}
impl std::fmt::Display for KeyValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Int(v) => write!(f, "{v}"),
Self::Text(v) => f.write_str(v),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RefreshKey {
pub entity: String,
pub key: KeyValue,
pub all: bool,
}
impl RefreshKey {
pub fn pk(entity: impl Into<String>, pk: i64) -> Self {
Self::new(entity, KeyValue::Int(pk))
}
pub fn new(entity: impl Into<String>, key: KeyValue) -> Self {
Self {
entity: entity.into(),
key,
all: false,
}
}
pub fn all(entity: impl Into<String>) -> Self {
Self {
entity: entity.into(),
key: KeyValue::Int(0),
all: true,
}
}
#[must_use]
pub const fn is_all(&self) -> bool {
self.all
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_refresh_key_equality() {
let key1 = RefreshKey::pk("user", 42);
let key2 = RefreshKey::pk("user", 42);
let key3 = RefreshKey::pk("user", 43);
assert_eq!(key1, key2);
assert_ne!(key1, key3);
}
#[test]
fn test_refresh_key_hashset_dedup() {
let mut set = std::collections::HashSet::new();
set.insert(RefreshKey::pk("user", 42));
set.insert(RefreshKey::pk("user", 42)); set.insert(RefreshKey::pk("post", 42));
assert_eq!(set.len(), 2);
}
#[test]
fn int_and_text_keys_differ_and_deduplicate() {
let mut set = std::collections::HashSet::new();
set.insert(RefreshKey::new("doc", KeyValue::Text("42".into())));
set.insert(RefreshKey::new("doc", KeyValue::Text("42".into())));
set.insert(RefreshKey::pk("doc", 42));
assert_eq!(set.len(), 2);
}
#[test]
fn test_all_key_is_distinct_and_deduplicated() {
let mut set = std::collections::HashSet::new();
set.insert(RefreshKey::all("order"));
set.insert(RefreshKey::all("order"));
set.insert(RefreshKey::pk("order", 0));
assert_eq!(set.len(), 2);
assert!(RefreshKey::all("order").is_all());
assert!(!RefreshKey::pk("order", 0).is_all());
}
#[test]
fn key_value_text_and_int() {
assert_eq!(KeyValue::Int(7).as_int(), Some(7));
assert_eq!(KeyValue::Text("a".into()).as_int(), None);
assert_eq!(KeyValue::Int(-3).to_string(), "-3");
assert_eq!(
KeyValue::Text("00000000-0000-0000-0000-000000000001".into()).to_string(),
"00000000-0000-0000-0000-000000000001"
);
}
}