1use crate::{
2 prepare_command,
3 resp::{cmd, ArgsOrCollection, CommandArg, CommandArgs, IntoArgs, SingleArgOrCollection},
4 PreparedCommand,
5};
6
7pub trait BitmapCommands {
13 #[must_use]
21 fn bitcount<K>(&mut self, key: K, range: BitRange) -> PreparedCommand<Self, usize>
22 where
23 Self: Sized,
24 K: Into<CommandArg>,
25 {
26 prepare_command(self, cmd("BITCOUNT").arg(key).arg(range))
27 }
28
29 #[must_use]
40 fn bitfield<K, C, E, O>(&mut self, key: K, sub_commands: C) -> PreparedCommand<Self, Vec<u64>>
41 where
42 Self: Sized,
43 K: Into<CommandArg>,
44 E: Into<CommandArg>,
45 O: Into<CommandArg>,
46 C: ArgsOrCollection<BitFieldSubCommand<E, O>>,
47 {
48 prepare_command(self, cmd("BITFIELD").arg(key).arg(sub_commands))
49 }
50
51 #[must_use]
62 fn bitfield_readonly<K, C, E, O>(
63 &mut self,
64 key: K,
65 get_commands: C,
66 ) -> PreparedCommand<Self, Vec<u64>>
67 where
68 Self: Sized,
69 K: Into<CommandArg>,
70 E: Into<CommandArg>,
71 O: Into<CommandArg>,
72 C: ArgsOrCollection<BitFieldGetSubCommand<E, O>>,
73 {
74 prepare_command(self, cmd("BITFIELD_RO").arg(key).arg(get_commands))
75 }
76
77 #[must_use]
87 fn bitop<D, K, KK>(
88 &mut self,
89 operation: BitOperation,
90 dest_key: D,
91 keys: KK,
92 ) -> PreparedCommand<Self, usize>
93 where
94 Self: Sized,
95 D: Into<CommandArg>,
96 K: Into<CommandArg>,
97 KK: SingleArgOrCollection<K>,
98 {
99 prepare_command(self, cmd("BITOP").arg(operation).arg(dest_key).arg(keys))
100 }
101
102 #[must_use]
111 fn bitpos<K>(&mut self, key: K, bit: u64, range: BitRange) -> PreparedCommand<Self, usize>
112 where
113 Self: Sized,
114 K: Into<CommandArg>,
115 {
116 prepare_command(self, cmd("BITPOS").arg(key).arg(bit).arg(range))
117 }
118
119 #[must_use]
127 fn getbit<K>(&mut self, key: K, offset: u64) -> PreparedCommand<Self, u64>
128 where
129 Self: Sized,
130 K: Into<CommandArg>,
131 {
132 prepare_command(self, cmd("GETBIT").arg(key).arg(offset))
133 }
134
135 #[must_use]
143 fn setbit<K>(&mut self, key: K, offset: u64, value: u64) -> PreparedCommand<Self, u64>
144 where
145 Self: Sized,
146 K: Into<CommandArg>,
147 {
148 prepare_command(self, cmd("SETBIT").arg(key).arg(offset).arg(value))
149 }
150}
151
152#[derive(Default)]
154pub struct BitRange {
155 command_args: CommandArgs,
156}
157
158impl BitRange {
159 #[must_use]
160 pub fn range(start: isize, end: isize) -> Self {
161 Self {
162 command_args: CommandArgs::default().arg(start).arg(end),
163 }
164 }
165
166 #[must_use]
167 pub fn unit(self, unit: BitUnit) -> Self {
168 Self {
169 command_args: self.command_args.arg(unit),
170 }
171 }
172}
173
174impl IntoArgs for BitRange {
175 fn into_args(self, args: CommandArgs) -> CommandArgs {
176 args.arg(self.command_args)
177 }
178}
179
180pub enum BitUnit {
181 Byte,
182 Bit,
183}
184
185impl IntoArgs for BitUnit {
186 fn into_args(self, args: CommandArgs) -> CommandArgs {
187 args.arg(match self {
188 BitUnit::Byte => "BYTE",
189 BitUnit::Bit => "BIT",
190 })
191 }
192}
193
194pub enum BitFieldSubCommand<E = &'static str, O = &'static str>
196where
197 E: Into<CommandArg>,
198 O: Into<CommandArg>,
199{
200 Get(BitFieldGetSubCommand<E, O>),
201 Set(E, O, u64),
202 IncrBy(E, O, i64),
203 Overflow(BitFieldOverflow),
204}
205
206impl<E, O> BitFieldSubCommand<E, O>
207where
208 E: Into<CommandArg>,
209 O: Into<CommandArg>,
210{
211 #[must_use]
212 pub fn get(encoding: E, offset: O) -> Self {
213 Self::Get(BitFieldGetSubCommand::new(encoding, offset))
214 }
215
216 #[must_use]
217 pub fn set(encoding: E, offset: O, value: u64) -> Self {
218 Self::Set(encoding, offset, value)
219 }
220
221 #[must_use]
222 pub fn incr_by(encoding: E, offset: O, increment: i64) -> Self {
223 Self::IncrBy(encoding, offset, increment)
224 }
225
226 #[must_use]
227 pub fn overflow(overflow: BitFieldOverflow) -> Self {
228 Self::Overflow(overflow)
229 }
230}
231
232impl<E, O> IntoArgs for BitFieldSubCommand<E, O>
233where
234 E: Into<CommandArg>,
235 O: Into<CommandArg>,
236{
237 fn into_args(self, args: CommandArgs) -> CommandArgs {
238 match self {
239 BitFieldSubCommand::Get(g) => g.into_args(args),
240 BitFieldSubCommand::Set(encoding, offset, value) => {
241 args.arg("SET").arg(encoding).arg(offset).arg(value)
242 }
243 BitFieldSubCommand::IncrBy(encoding, offset, increment) => {
244 args.arg("INCRBY").arg(encoding).arg(offset).arg(increment)
245 }
246 BitFieldSubCommand::Overflow(overflow) => args.arg("OVERFLOW").arg(overflow),
247 }
248 }
249}
250
251pub struct BitFieldGetSubCommand<E = &'static str, O = &'static str>
252where
253 E: Into<CommandArg>,
254 O: Into<CommandArg>,
255{
256 encoding: E,
257 offset: O,
258}
259
260impl<E, O> BitFieldGetSubCommand<E, O>
261where
262 E: Into<CommandArg>,
263 O: Into<CommandArg>,
264{
265 #[must_use]
266 pub fn new(encoding: E, offset: O) -> Self {
267 Self { encoding, offset }
268 }
269}
270
271impl<E, O> IntoArgs for BitFieldGetSubCommand<E, O>
272where
273 E: Into<CommandArg>,
274 O: Into<CommandArg>,
275{
276 fn into_args(self, args: CommandArgs) -> CommandArgs {
277 args.arg("GET").arg(self.encoding).arg(self.offset)
278 }
279}
280
281pub enum BitFieldOverflow {
282 Wrap,
283 Sat,
284 Fail,
285}
286
287impl IntoArgs for BitFieldOverflow {
288 fn into_args(self, args: CommandArgs) -> CommandArgs {
289 args.arg(match self {
290 BitFieldOverflow::Wrap => "WRAP",
291 BitFieldOverflow::Sat => "SAT",
292 BitFieldOverflow::Fail => "FAIL",
293 })
294 }
295}
296
297pub enum BitOperation {
299 And,
300 Or,
301 Xor,
302 Not,
303}
304
305impl IntoArgs for BitOperation {
306 fn into_args(self, args: CommandArgs) -> CommandArgs {
307 args.arg(match self {
308 BitOperation::And => "AND",
309 BitOperation::Or => "OR",
310 BitOperation::Xor => "XOR",
311 BitOperation::Not => "NOT",
312 })
313 }
314}