use super::{utils, Command, CommandError};
use crate::codec_redis::{BulkString, Request, Response};
use std::convert::TryFrom;
pub fn Del<T>(key: T) -> KeysCommand
where
BulkString: From<T>,
{
KeysCommand(vec![
Request::from_static("DEL"),
Request::BulkString(key.into()),
])
}
pub fn Exists<T>(key: T) -> KeysCommand
where
BulkString: From<T>,
{
KeysCommand(vec![
Request::from_static("EXISTS"),
Request::BulkString(key.into()),
])
}
pub struct KeysCommand(Vec<Request>);
impl KeysCommand {
pub fn key<T>(mut self, other: T) -> Self
where
BulkString: From<T>,
{
self.0.push(other.into());
self
}
pub fn keys<T>(mut self, other: impl IntoIterator<Item = T>) -> Self
where
BulkString: From<T>,
{
self.0.extend(other.into_iter().map(|t| t.into()));
self
}
}
impl Command for KeysCommand {
type Output = usize;
fn to_request(self) -> Request {
Request::Array(self.0)
}
fn to_output(val: Response) -> Result<Self::Output, CommandError> {
match val {
Response::Integer(val) => Ok(val as usize),
_ => Err(CommandError::Output("Cannot parse response", val)),
}
}
}
pub fn Expire<T, S>(key: T, seconds: S) -> utils::BoolOutputCommand
where
BulkString: From<T>,
i64: From<S>,
{
utils::BoolOutputCommand(Request::Array(vec![
Request::from_static("EXPIRE"),
Request::BulkString(key.into()),
Request::BulkString(i64::from(seconds).to_string().into()),
]))
}
pub fn ExpireAt<T, S>(key: T, timestamp: S) -> utils::BoolOutputCommand
where
BulkString: From<T>,
i64: From<S>,
{
utils::BoolOutputCommand(Request::Array(vec![
Request::from_static("EXPIREAT"),
Request::BulkString(key.into()),
Request::BulkString(i64::from(timestamp).to_string().into()),
]))
}
pub fn Ttl<T>(key: T) -> TtlCommand
where
BulkString: From<T>,
{
TtlCommand(vec![
Request::from_static("TTL"),
Request::BulkString(key.into()),
])
}
#[derive(Debug, PartialEq)]
pub enum TtlResult {
Seconds(i64),
NoExpire,
NotFound,
}
pub struct TtlCommand(Vec<Request>);
impl Command for TtlCommand {
type Output = TtlResult;
fn to_request(self) -> Request {
Request::Array(self.0)
}
fn to_output(val: Response) -> Result<Self::Output, CommandError> {
let result = i64::try_from(val)?;
Ok(match result {
-1 => TtlResult::NoExpire,
-2 => TtlResult::NotFound,
s => TtlResult::Seconds(s),
})
}
}