use super::meta_api::{ArithmeticMode, SetMode};
use super::value::ToValue;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Meta {
pub cas: bool,
pub ttl: bool,
pub size: bool,
pub last_access: bool,
pub hit_before: bool,
}
impl Meta {
pub const NONE: Meta = Meta {
cas: false,
ttl: false,
size: false,
last_access: false,
hit_before: false,
};
pub const ALL: Meta = Meta {
cas: true,
ttl: true,
size: true,
last_access: true,
hit_before: true,
};
#[must_use]
pub fn cas(mut self) -> Meta {
self.cas = true;
self
}
#[must_use]
pub fn ttl(mut self) -> Meta {
self.ttl = true;
self
}
#[must_use]
pub fn size(mut self) -> Meta {
self.size = true;
self
}
#[must_use]
pub fn last_access(mut self) -> Meta {
self.last_access = true;
self
}
#[must_use]
pub fn hit_before(mut self) -> Meta {
self.hit_before = true;
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Get {
pub key: Vec<u8>,
pub meta: Meta,
pub touch: Option<u32>,
pub no_lru_bump: bool,
pub unless_cas: Option<u64>,
pub value: bool,
pub lease_ttl: Option<u32>,
pub refresh_before: Option<u32>,
}
impl Get {
pub fn new(key: impl Into<Vec<u8>>) -> Get {
Get {
key: key.into(),
meta: Meta::NONE,
touch: None,
no_lru_bump: false,
unless_cas: None,
value: true,
lease_ttl: None,
refresh_before: None,
}
}
#[must_use]
pub fn meta(mut self, meta: Meta) -> Get {
self.meta = meta;
self
}
#[must_use]
pub fn touch(mut self, ttl: u32) -> Get {
self.touch = Some(ttl);
self
}
#[must_use]
pub fn no_lru_bump(mut self) -> Get {
self.no_lru_bump = true;
self
}
#[must_use]
pub fn unless_cas(mut self, cas: u64) -> Get {
self.unless_cas = Some(cas);
self
}
#[must_use]
pub fn without_value(mut self) -> Get {
self.value = false;
self
}
#[must_use]
pub fn lease_ttl(mut self, ttl: u32) -> Get {
self.lease_ttl = Some(ttl);
self
}
#[must_use]
pub fn refresh_before(mut self, ttl: u32) -> Get {
self.refresh_before = Some(ttl);
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Set {
pub key: Vec<u8>,
pub value: Vec<u8>,
pub client_flags: u32,
pub ttl: Option<u32>,
pub mode: SetMode,
pub compare_cas: Option<u64>,
pub version: Option<u64>,
pub return_cas: bool,
pub vivify_ttl: Option<u32>,
}
impl Set {
pub fn new(key: impl Into<Vec<u8>>, value: impl ToValue) -> Set {
let (value, client_flags) = value.to_value();
Set {
key: key.into(),
value,
client_flags,
ttl: None,
mode: SetMode::Set,
compare_cas: None,
version: None,
return_cas: false,
vivify_ttl: None,
}
}
#[must_use]
pub fn ttl(mut self, ttl: u32) -> Set {
self.ttl = Some(ttl);
self
}
#[must_use]
pub fn mode(mut self, mode: SetMode) -> Set {
self.mode = mode;
self
}
#[must_use]
pub fn add(self) -> Set {
self.mode(SetMode::Add)
}
#[must_use]
pub fn replace(self) -> Set {
self.mode(SetMode::Replace)
}
#[must_use]
pub fn append(self) -> Set {
self.mode(SetMode::Append)
}
#[must_use]
pub fn prepend(self) -> Set {
self.mode(SetMode::Prepend)
}
#[must_use]
pub fn compare_cas(mut self, cas: u64) -> Set {
self.compare_cas = Some(cas);
self
}
#[must_use]
pub fn version(mut self, version: u64) -> Set {
self.version = Some(version);
self
}
#[must_use]
pub fn return_cas(mut self) -> Set {
self.return_cas = true;
self
}
#[must_use]
pub fn vivify_ttl(mut self, ttl: u32) -> Set {
self.vivify_ttl = Some(ttl);
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Delete {
pub key: Vec<u8>,
pub compare_cas: Option<u64>,
pub invalidate: bool,
pub stale_for: Option<u32>,
}
impl Delete {
pub fn new(key: impl Into<Vec<u8>>) -> Delete {
Delete {
key: key.into(),
compare_cas: None,
invalidate: false,
stale_for: None,
}
}
#[must_use]
pub fn compare_cas(mut self, cas: u64) -> Delete {
self.compare_cas = Some(cas);
self
}
#[must_use]
pub fn invalidate(mut self) -> Delete {
self.invalidate = true;
self
}
#[must_use]
pub fn stale_for(mut self, ttl: u32) -> Delete {
self.stale_for = Some(ttl);
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Arithmetic {
pub key: Vec<u8>,
pub delta: u64,
pub mode: ArithmeticMode,
pub initial: Option<u64>,
pub initial_ttl: Option<u32>,
pub ttl: Option<u32>,
pub compare_cas: Option<u64>,
pub version: Option<u64>,
pub return_cas: bool,
pub return_ttl: bool,
}
impl Arithmetic {
pub fn new(key: impl Into<Vec<u8>>) -> Arithmetic {
Arithmetic {
key: key.into(),
delta: 1,
mode: ArithmeticMode::Increment,
initial: None,
initial_ttl: None,
ttl: None,
compare_cas: None,
version: None,
return_cas: false,
return_ttl: false,
}
}
#[must_use]
pub fn delta(mut self, delta: u64) -> Arithmetic {
self.delta = delta;
self
}
#[must_use]
pub fn decrement(mut self) -> Arithmetic {
self.mode = ArithmeticMode::Decrement;
self
}
#[must_use]
pub fn initial(mut self, value: u64, ttl: u32) -> Arithmetic {
self.initial = Some(value);
self.initial_ttl = Some(ttl);
self
}
#[must_use]
pub fn ttl(mut self, ttl: u32) -> Arithmetic {
self.ttl = Some(ttl);
self
}
#[must_use]
pub fn compare_cas(mut self, cas: u64) -> Arithmetic {
self.compare_cas = Some(cas);
self
}
#[must_use]
pub fn version(mut self, version: u64) -> Arithmetic {
self.version = Some(version);
self
}
#[must_use]
pub fn return_cas(mut self) -> Arithmetic {
self.return_cas = true;
self
}
#[must_use]
pub fn return_ttl(mut self) -> Arithmetic {
self.return_ttl = true;
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Op {
Get(Get),
Set(Set),
Delete(Delete),
Arithmetic(Arithmetic),
}
impl From<Get> for Op {
fn from(operation: Get) -> Op {
Op::Get(operation)
}
}
impl From<Set> for Op {
fn from(operation: Set) -> Op {
Op::Set(operation)
}
}
impl From<Delete> for Op {
fn from(operation: Delete) -> Op {
Op::Delete(operation)
}
}
impl From<Arithmetic> for Op {
fn from(operation: Arithmetic) -> Op {
Op::Arithmetic(operation)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn builders_set_fields() {
let get = Get::new("foo")
.meta(Meta::NONE.cas().ttl())
.touch(60)
.no_lru_bump()
.lease_ttl(30)
.refresh_before(10);
assert!(get.meta.cas && get.meta.ttl && !get.meta.size);
assert_eq!(get.touch, Some(60));
assert!(get.no_lru_bump);
assert_eq!(get.lease_ttl, Some(30));
assert_eq!(get.refresh_before, Some(10));
assert!(!Get::new("foo").without_value().value);
let set = Set::new("foo", "bar").ttl(60).add().compare_cas(7).return_cas();
assert_eq!(set.ttl, Some(60));
assert_eq!(set.mode, SetMode::Add);
assert_eq!(set.compare_cas, Some(7));
assert!(set.return_cas);
let delete = Delete::new("foo").invalidate().stale_for(30);
assert!(delete.invalidate);
assert_eq!(delete.stale_for, Some(30));
let arithmetic = Arithmetic::new("counter").delta(2).decrement().initial(0, 60);
assert_eq!(arithmetic.delta, 2);
assert_eq!(arithmetic.mode, ArithmeticMode::Decrement);
assert_eq!(arithmetic.initial, Some(0));
assert_eq!(arithmetic.initial_ttl, Some(60));
}
}