1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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()),
]))
}