use crate::{
Result,
client::{MonitorStream, PreparedCommand, prepare_command},
commands::{LMoveWhere, ZMPopResult, ZWhere},
resp::{Response, cmd, deserialize_vec_of_triplets},
};
use serde::{
Deserialize, Deserializer, Serialize,
de::{DeserializeOwned, Visitor},
};
use std::{fmt, marker::PhantomData};
#[derive(Deserialize)]
pub struct BZpopMinMaxResult<K, E>(
#[serde(deserialize_with = "deserialize_bzop_min_max_result")] pub Option<Vec<(K, E, f64)>>,
)
where
K: DeserializeOwned,
E: DeserializeOwned;
#[allow(clippy::complexity)]
pub(crate) fn deserialize_bzop_min_max_result<'de, D, K, V>(
deserializer: D,
) -> std::result::Result<Option<Vec<(K, V, f64)>>, D::Error>
where
D: Deserializer<'de>,
K: DeserializeOwned,
V: DeserializeOwned,
{
struct OptionVisitor<K, V> {
phantom: PhantomData<(K, V)>,
}
impl<'de, K, V> Visitor<'de> for OptionVisitor<K, V>
where
K: DeserializeOwned,
V: DeserializeOwned,
{
type Value = Option<Vec<(K, V, f64)>>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("Option<Vec<(K, V, f64)>>")
}
fn visit_none<E>(self) -> std::result::Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(None)
}
fn visit_some<D>(self, deserializer: D) -> std::result::Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
deserialize_vec_of_triplets(deserializer).map(Some)
}
}
deserializer.deserialize_option(OptionVisitor {
phantom: PhantomData,
})
}
pub trait BlockingCommands<'a>: Sized {
#[must_use]
fn blmove<R: Response>(
self,
source: impl Serialize,
destination: impl Serialize,
where_from: LMoveWhere,
where_to: LMoveWhere,
timeout: f64,
) -> PreparedCommand<'a, Self, R> {
prepare_command(
self,
cmd("BLMOVE")
.key(source)
.key(destination)
.arg(where_from)
.arg(where_to)
.arg(timeout),
)
}
#[must_use]
fn blmpop<R: Response + DeserializeOwned>(
self,
timeout: f64,
keys: impl Serialize,
where_: LMoveWhere,
count: usize,
) -> PreparedCommand<'a, Self, Option<(String, R)>> {
prepare_command(
self,
cmd("BLMPOP")
.arg(timeout)
.key_with_count(keys)
.arg(where_)
.arg("COUNT")
.arg(count),
)
}
#[must_use]
fn blpop<R1: Response + DeserializeOwned, R2: Response + DeserializeOwned>(
self,
keys: impl Serialize,
timeout: f64,
) -> PreparedCommand<'a, Self, Option<(R1, R2)>> {
prepare_command(self, cmd("BLPOP").key(keys).arg(timeout))
}
#[must_use]
fn brpop<R1: Response + DeserializeOwned, R2: Response + DeserializeOwned>(
self,
keys: impl Serialize,
timeout: f64,
) -> PreparedCommand<'a, Self, Option<(R1, R2)>> {
prepare_command(self, cmd("BRPOP").key(keys).arg(timeout))
}
#[must_use]
fn bzmpop<R: Response + DeserializeOwned>(
self,
timeout: f64,
keys: impl Serialize,
where_: ZWhere,
count: usize,
) -> PreparedCommand<'a, Self, Option<ZMPopResult<R>>> {
prepare_command(
self,
cmd("BZMPOP")
.arg(timeout)
.key_with_count(keys)
.arg(where_)
.arg("COUNT")
.arg(count),
)
}
#[must_use]
fn bzpopmax<R1: Response + DeserializeOwned, R2: Response + DeserializeOwned>(
self,
keys: impl Serialize,
timeout: f64,
) -> PreparedCommand<'a, Self, BZpopMinMaxResult<R1, R2>> {
prepare_command(self, cmd("BZPOPMAX").key(keys).arg(timeout))
}
#[must_use]
fn bzpopmin<R1: Response + DeserializeOwned, R2: Response + DeserializeOwned>(
self,
keys: impl Serialize,
timeout: f64,
) -> PreparedCommand<'a, Self, BZpopMinMaxResult<R1, R2>> {
prepare_command(self, cmd("BZPOPMIN").key(keys).arg(timeout))
}
#[must_use]
#[allow(async_fn_in_trait)]
async fn monitor(self) -> Result<MonitorStream>;
}