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