use super::{utils, Command, CommandError};
use crate::codec::{BulkString, Request, Response};
pub fn Get<T>(key: T) -> utils::BulkOutputCommand
where
BulkString: From<T>,
{
utils::BulkOutputCommand(Request::Array(vec![
Request::from_static("GET"),
Request::BulkString(key.into()),
]))
}
pub fn Set<T, V>(key: T, value: V) -> SetCommand
where
BulkString: From<T> + From<V>,
{
SetCommand {
req: vec![
Request::from_bstatic(b"SET"),
Request::BulkString(key.into()),
Request::BulkString(value.into()),
],
expire: Expire::None,
keepttl: false,
exists: None,
}
}
enum Expire {
None,
Ex(Request),
Px(Request),
}
pub struct SetCommand {
req: Vec<Request>,
expire: Expire,
keepttl: bool,
exists: Option<bool>,
}
impl SetCommand {
pub fn expire_secs(mut self, secs: i64) -> Self {
self.expire = Expire::Ex(Request::BulkInteger(secs));
self
}
pub fn expire_millis(mut self, secs: i64) -> Self {
self.expire = Expire::Px(Request::BulkInteger(secs));
self
}
pub fn if_exists(mut self) -> Self {
self.exists = Some(true);
self
}
pub fn if_not_exists(mut self) -> Self {
self.exists = Some(false);
self
}
pub fn keepttl(mut self) -> Self {
self.keepttl = true;
self
}
}
impl Command for SetCommand {
type Output = bool;
fn to_request(mut self) -> Request {
match self.expire {
Expire::None => (),
Expire::Ex(r) => {
self.req.push(Request::from_bstatic(b"EX"));
self.req.push(r);
}
Expire::Px(r) => {
self.req.push(Request::from_bstatic(b"PX"));
self.req.push(r);
}
}
if let Some(exists) = self.exists {
self.req.push(if exists {
Request::from_bstatic(b"XX")
} else {
Request::from_bstatic(b"NX")
});
}
if self.keepttl {
self.req.push(Request::from_bstatic(b"KEEPTTL"))
}
Request::Array(self.req)
}
fn to_output(val: Response) -> Result<Self::Output, CommandError> {
match val {
Response::Nil => Ok(false),
Response::String(string) => match string.as_ref() {
"OK" => Ok(true),
_ => Err(CommandError::Output(
"Unexpected value within String",
Response::String(string),
)),
},
_ => Err(CommandError::Output("Unexpected value", val)),
}
}
}
pub fn IncrBy<T, I>(key: T, increment: I) -> utils::IntOutputCommand
where
BulkString: From<T>,
i64: From<I>,
{
utils::IntOutputCommand(Request::Array(vec![
Request::from_static("INCRBY"),
Request::BulkString(key.into()),
Request::BulkString(i64::from(increment).to_string().into()),
]))
}