1use super::{utils, Command, CommandError};
2use crate::codec_redis::{BulkString, Request, Response};
3
4pub fn Get<T>(key: T) -> utils::BulkOutputCommand
6where
7 BulkString: From<T>,
8{
9 utils::BulkOutputCommand(Request::Array(vec![
10 Request::from_static("GET"),
11 Request::BulkString(key.into()),
12 ]))
13}
14
15pub fn Set<T, V>(key: T, value: V) -> SetCommand
20where
21 BulkString: From<T> + From<V>,
22{
23 SetCommand {
24 req: vec![
25 Request::from_bstatic(b"SET"),
26 Request::BulkString(key.into()),
27 Request::BulkString(value.into()),
28 ],
29 expire: Expire::None,
30 keepttl: false,
31 exists: None,
32 }
33}
34
35enum Expire {
36 None,
37 Ex(Request),
38 Px(Request),
39}
40
41pub struct SetCommand {
42 req: Vec<Request>,
43 expire: Expire,
44 keepttl: bool,
45 exists: Option<bool>,
46}
47
48impl SetCommand {
49 pub fn expire_secs(mut self, secs: i64) -> Self {
51 self.expire = Expire::Ex(Request::BulkInteger(secs));
52 self
53 }
54
55 pub fn expire_millis(mut self, secs: i64) -> Self {
57 self.expire = Expire::Px(Request::BulkInteger(secs));
58 self
59 }
60
61 pub fn if_exists(mut self) -> Self {
63 self.exists = Some(true);
64 self
65 }
66
67 pub fn if_not_exists(mut self) -> Self {
69 self.exists = Some(false);
70 self
71 }
72
73 pub fn keepttl(mut self) -> Self {
75 self.keepttl = true;
76 self
77 }
78}
79
80impl Command for SetCommand {
81 type Output = bool;
82
83 fn to_request(mut self) -> Request {
84 match self.expire {
86 Expire::None => (),
87 Expire::Ex(r) => {
88 self.req.push(Request::from_bstatic(b"EX"));
89 self.req.push(r);
90 }
91 Expire::Px(r) => {
92 self.req.push(Request::from_bstatic(b"PX"));
93 self.req.push(r);
94 }
95 }
96
97 if let Some(exists) = self.exists {
99 self.req.push(if exists {
100 Request::from_bstatic(b"XX")
101 } else {
102 Request::from_bstatic(b"NX")
103 });
104 }
105
106 if self.keepttl {
108 self.req.push(Request::from_bstatic(b"KEEPTTL"))
109 }
110
111 Request::Array(self.req)
112 }
113
114 fn to_output(val: Response) -> Result<Self::Output, CommandError> {
115 match val {
116 Response::Nil => Ok(false),
117 Response::String(string) => match string.as_ref() {
118 "OK" => Ok(true),
119 _ => Err(CommandError::Output(
120 "Unexpected value within String",
121 Response::String(string),
122 )),
123 },
124 _ => Err(CommandError::Output("Unexpected value", val)),
125 }
126 }
127}
128
129pub fn IncrBy<T, I>(key: T, increment: I) -> utils::IntOutputCommand
133where
134 BulkString: From<T>,
135 i64: From<I>,
136{
137 utils::IntOutputCommand(Request::Array(vec![
138 Request::from_static("INCRBY"),
139 Request::BulkString(key.into()),
140 Request::BulkString(i64::from(increment).to_string().into()),
141 ]))
142}