use std::convert::{TryFrom, TryInto};
use ntex::util::ByteString;
use super::{utils, Command, CommandError};
use crate::codec::{BulkString, Request, Response};
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, Eq)]
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),
})
}
}
pub fn Keys<T>(key: T) -> KeysPatternCommand
where
BulkString: From<T>,
{
KeysPatternCommand(Request::Array(vec![
Request::from_static("KEYS"),
Request::BulkString(key.into()),
]))
}
pub struct KeysPatternCommand(Request);
impl Command for KeysPatternCommand {
type Output = Vec<ByteString>;
fn to_request(self) -> Request {
self.0
}
fn to_output(val: Response) -> Result<Self::Output, CommandError> {
match val.try_into() {
Ok(val) => Ok(val),
Err((_, val)) => Err(CommandError::Output("Cannot parse response", val)),
}
}
}