use crate::{
client::{PreparedCommand, prepare_command},
resp::{Response, cmd, serialize_flag},
};
use serde::{Deserialize, Serialize};
use smallvec::SmallVec;
pub trait ArrayCommands<'a>: Sized {
#[must_use]
fn arcount(self, key: impl Serialize) -> PreparedCommand<'a, Self, usize> {
prepare_command(self, cmd("ARCOUNT").key(key).readonly())
}
#[must_use]
fn ardel(
self,
key: impl Serialize,
indices: impl Serialize,
) -> PreparedCommand<'a, Self, usize> {
prepare_command(self, cmd("ARDEL").key(key).arg(indices))
}
#[must_use]
fn ardelrange(
self,
key: impl Serialize,
ranges: impl Serialize,
) -> PreparedCommand<'a, Self, usize> {
prepare_command(self, cmd("ARDELRANGE").key(key).arg(ranges))
}
#[must_use]
fn arget<R: Response>(self, key: impl Serialize, index: usize) -> PreparedCommand<'a, Self, R> {
prepare_command(self, cmd("ARGET").key(key).arg(index).readonly())
}
#[must_use]
fn argetrange<R: Response>(
self,
key: impl Serialize,
start: usize,
end: usize,
) -> PreparedCommand<'a, Self, R> {
prepare_command(
self,
cmd("ARGETRANGE").key(key).arg(start).arg(end).readonly(),
)
}
#[must_use]
fn argrep<R: Response>(
self,
key: impl Serialize,
start: impl Serialize,
end: impl Serialize,
options: ArGrep,
) -> PreparedCommand<'a, Self, R> {
prepare_command(
self,
cmd("ARGREP")
.key(key)
.arg(start)
.arg(end)
.arg(options)
.readonly(),
)
}
#[must_use]
fn arinfo(
self,
key: impl Serialize,
options: ArInfoOptions,
) -> PreparedCommand<'a, Self, ArrayInfo> {
prepare_command(self, cmd("ARINFO").key(key).arg(options).readonly())
}
#[must_use]
fn arinsert(
self,
key: impl Serialize,
values: impl Serialize,
) -> PreparedCommand<'a, Self, usize> {
prepare_command(self, cmd("ARINSERT").key(key).arg(values))
}
#[must_use]
fn arlastitems<R: Response>(
self,
key: impl Serialize,
count: usize,
options: ArLastItemsOptions,
) -> PreparedCommand<'a, Self, R> {
prepare_command(
self,
cmd("ARLASTITEMS")
.key(key)
.arg(count)
.arg(options)
.readonly(),
)
}
#[must_use]
fn arlen(self, key: impl Serialize) -> PreparedCommand<'a, Self, usize> {
prepare_command(self, cmd("ARLEN").key(key).readonly())
}
#[must_use]
fn armget<R: Response>(
self,
key: impl Serialize,
indices: impl Serialize,
) -> PreparedCommand<'a, Self, R> {
prepare_command(self, cmd("ARMGET").key(key).arg(indices).readonly())
}
#[must_use]
fn armset(
self,
key: impl Serialize,
items: impl Serialize,
) -> PreparedCommand<'a, Self, usize> {
prepare_command(self, cmd("ARMSET").key(key).arg(items))
}
#[must_use]
fn arnext(self, key: impl Serialize) -> PreparedCommand<'a, Self, usize> {
prepare_command(self, cmd("ARNEXT").key(key).readonly())
}
#[must_use]
fn arop<R: Response>(
self,
key: impl Serialize,
start: usize,
end: usize,
operation: ArOperation<'_>,
) -> PreparedCommand<'a, Self, R> {
prepare_command(
self,
cmd("AROP")
.key(key)
.arg(start)
.arg(end)
.arg(operation)
.readonly(),
)
}
#[must_use]
fn arring(
self,
key: impl Serialize,
size: usize,
values: impl Serialize,
) -> PreparedCommand<'a, Self, usize> {
prepare_command(self, cmd("ARRING").key(key).arg(size).arg(values))
}
#[must_use]
fn arscan<R: Response>(
self,
key: impl Serialize,
start: usize,
end: usize,
limit: impl Into<Option<usize>>,
) -> PreparedCommand<'a, Self, R> {
prepare_command(
self,
cmd("ARSCAN")
.key(key)
.arg(start)
.arg(end)
.arg_labeled("LIMIT", limit.into())
.readonly(),
)
}
#[must_use]
fn arseek(self, key: impl Serialize, index: usize) -> PreparedCommand<'a, Self, bool> {
prepare_command(self, cmd("ARSEEK").key(key).arg(index))
}
#[must_use]
fn arset(
self,
key: impl Serialize,
index: usize,
values: impl Serialize,
) -> PreparedCommand<'a, Self, usize> {
prepare_command(self, cmd("ARSET").key(key).arg(index).arg(values))
}
}
#[derive(Default, Serialize)]
#[serde(rename_all = "UPPERCASE")]
pub struct ArInfoOptions {
#[serde(
skip_serializing_if = "std::ops::Not::not",
serialize_with = "serialize_flag"
)]
full: bool,
}
impl ArInfoOptions {
#[must_use]
pub fn full(mut self) -> Self {
self.full = true;
self
}
}
#[derive(Default, Serialize)]
#[serde(rename_all = "UPPERCASE")]
pub struct ArLastItemsOptions {
#[serde(
skip_serializing_if = "std::ops::Not::not",
serialize_with = "serialize_flag"
)]
rev: bool,
}
impl ArLastItemsOptions {
#[must_use]
pub fn rev(mut self) -> Self {
self.rev = true;
self
}
}
#[derive(Serialize)]
#[serde(rename_all = "UPPERCASE")]
#[non_exhaustive]
pub enum ArOperation<'a> {
Sum,
Min,
Max,
And,
Or,
Xor,
Match(&'a str),
Used,
}
#[derive(Serialize)]
#[serde(rename_all = "UPPERCASE")]
#[non_exhaustive]
pub enum ArGrepPredicate<'a> {
Exact(&'a str),
Match(&'a str),
Glob(&'a str),
Re(&'a str),
}
#[derive(Serialize)]
#[serde(rename_all = "UPPERCASE")]
pub struct ArGrep<'a> {
#[serde(rename = "")]
predicates: SmallVec<[ArGrepPredicate<'a>; 4]>,
#[serde(rename = "", skip_serializing_if = "Option::is_none")]
combine: Option<ArGrepCombine>,
#[serde(skip_serializing_if = "Option::is_none")]
limit: Option<usize>,
#[serde(
skip_serializing_if = "std::ops::Not::not",
serialize_with = "serialize_flag"
)]
withvalues: bool,
#[serde(
skip_serializing_if = "std::ops::Not::not",
serialize_with = "serialize_flag"
)]
nocase: bool,
}
#[derive(Serialize)]
#[serde(rename_all = "UPPERCASE")]
enum ArGrepCombine {
And,
Or,
}
impl<'a> ArGrep<'a> {
#[must_use]
pub fn new(predicate: ArGrepPredicate<'a>) -> Self {
let mut predicates = SmallVec::new();
predicates.push(predicate);
Self {
predicates,
combine: None,
limit: None,
withvalues: false,
nocase: false,
}
}
#[must_use]
pub fn predicate(mut self, predicate: ArGrepPredicate<'a>) -> Self {
self.predicates.push(predicate);
self
}
#[must_use]
pub fn and(mut self) -> Self {
self.combine = Some(ArGrepCombine::And);
self
}
#[must_use]
pub fn or(mut self) -> Self {
self.combine = Some(ArGrepCombine::Or);
self
}
#[must_use]
pub fn limit(mut self, limit: usize) -> Self {
self.limit = Some(limit);
self
}
#[must_use]
pub fn with_values(mut self) -> Self {
self.withvalues = true;
self
}
#[must_use]
pub fn nocase(mut self) -> Self {
self.nocase = true;
self
}
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub struct ArrayInfo {
pub count: usize,
pub len: usize,
pub next_insert_index: usize,
pub slices: usize,
pub directory_size: usize,
pub super_dir_entries: usize,
pub slice_size: usize,
#[serde(default)]
pub dense_slices: Option<usize>,
#[serde(default)]
pub sparse_slices: Option<usize>,
#[serde(default)]
pub avg_dense_size: Option<f64>,
#[serde(default)]
pub avg_dense_fill: Option<f64>,
#[serde(default)]
pub avg_sparse_size: Option<f64>,
}