use std::fmt::Debug;
#[cfg(feature = "serilize")]
use bytes::Buf;
use chrono::prelude::*;
#[cfg(feature = "serilize")]
use serde::{de::DeserializeOwned, Deserialize, Serialize};
#[cfg(feature = "serilize")]
use crate::codec::Codec;
#[derive(Debug, Clone)]
pub struct Entry<K, V> {
pub key: K,
pub value: Option<V>,
pub expire_at_ms: Option<i64>,
}
pub trait EntryTrait<K> {
fn get_key(&self) -> K;
fn is_expired(&self) -> bool;
}
impl<K, V> EntryTrait<K> for Entry<K, V>
where
K: Clone,
{
fn is_expired(&self) -> bool {
if self.expire_at_ms.is_none() {
return false;
}
Utc.timestamp_millis_opt(self.expire_at_ms.unwrap())
.unwrap()
< Utc::now()
}
fn get_key(&self) -> K {
self.key.clone()
}
}
#[cfg(feature = "serilize")]
pub trait SerilizableEntryTrait {
fn decode(data: bytes::Bytes) -> anyhow::Result<Self>
where
Self: Sized;
fn encode(&self) -> anyhow::Result<bytes::Bytes>;
}
#[cfg(feature = "serilize")]
impl<K, V> SerilizableEntryTrait for Entry<K, V>
where
K: Serialize + DeserializeOwned + Clone,
V: Codec,
{
fn decode(data: bytes::Bytes) -> anyhow::Result<Self> {
let eni: EntryInner<K> = serde_json::from_reader(data.reader())?;
let value = if eni.value_data.is_empty() {
None
} else {
Some(V::decode(eni.value_data.into())?)
};
Ok(Self {
key: eni.key,
value,
expire_at_ms: eni.expire_at_ms,
})
}
fn encode(&self) -> anyhow::Result<bytes::Bytes> {
let value_data = match &self.value {
Some(v) => v.encode()?.to_vec(),
None => vec![],
};
let eni = EntryInner {
key: self.key.clone(),
value_data,
expire_at_ms: self.expire_at_ms,
};
Ok(serde_json::to_vec(&eni)?.into())
}
}
#[cfg(feature = "serilize")]
#[derive(Serialize, Deserialize)]
struct EntryInner<K> {
key: K,
value_data: Vec<u8>,
expire_at_ms: Option<i64>,
}