#![allow(dead_code)]
use rustis::{
Result,
client::{BatchPreparedCommand, Client, ExclusiveClient, IntoConfig, Pipeline, Transaction},
commands::{
BlockingCommands, GenericCommands, HashCommands, ListCommands, ServerCommands,
SortedSetCommands, StringCommands, TransactionCommands, VectorSetCommands,
},
resp::cmd,
};
async fn pipeline_queues_every_family(client: &Client) -> Result<()> {
let mut pipeline: Pipeline<'_> = client.create_pipeline();
pipeline.set("key", "value").queue();
pipeline.get::<()>("key").queue();
pipeline.del("key").forget();
pipeline.hset("hash", ("field", "value")).queue();
pipeline.lpush("list", "value").queue();
pipeline
.zadd("zset", [(1.0, "member")], Default::default())
.queue();
pipeline
.vadd("vset", None, &[1.0, 2.0], "element", Default::default())
.queue();
pipeline.dbsize().queue();
let (_, _): (String, usize) = pipeline.execute().await?;
Ok(())
}
async fn transaction_queues_every_family(client: &Client) -> Result<()> {
let mut transaction: Transaction = client.create_transaction();
transaction.set("key", "value").forget();
transaction.get::<()>("key").queue();
transaction.hset("hash", ("field", "value")).queue();
transaction.lpush("list", "value").queue();
transaction
.zadd("zset", [(1.0, "member")], Default::default())
.queue();
transaction
.vadd("vset", None, &[1.0, 2.0], "element", Default::default())
.queue();
transaction.dbsize().queue();
let _: (String, usize) = transaction.execute().await?;
Ok(())
}
async fn exclusive_client_owns_the_reserved_families(config: impl IntoConfig) -> Result<()> {
let client = ExclusiveClient::connect(config).await?;
let _: Option<(String, String)> = client.blpop("list", 0.0).await?;
client.watch("key").await?;
client.unwatch().await?;
client.set("key", "value").await?;
Ok(())
}
async fn the_two_client_shapes(config: impl IntoConfig) -> Result<()> {
let client = Client::connect(config).await?;
let _clone = client.clone();
let _exclusive: ExclusiveClient = client.into_exclusive()?;
Ok(())
}
async fn generic_commands(client: &Client) -> Result<()> {
let _: String = client.send(cmd("GET").key("key"), None).await?;
Ok(())
}
#[test]
fn errors_can_be_classified_from_outside() {
use rustis::{Error, ErrorKind, TimeoutKind};
let error: Error = ErrorKind::Timeout(TimeoutKind::Command).into();
assert!(error.is_timeout());
assert!(error.is_retryable());
assert!(!error.is_server_error());
assert!(matches!(error.kind(), ErrorKind::Timeout(_)));
}
#[test]
fn a_config_round_trips_through_its_uri() {
use rustis::client::{Config, IntoConfig};
let config: Config = "redis://127.0.0.1:6379/1?command_timeout=5000"
.into_config()
.expect("a well-formed URI parses");
assert_eq!(5000, config.command_timeout.as_millis());
let error = "redis://127.0.0.1:6379?not_a_parameter=1"
.into_config()
.expect_err("an unknown parameter is rejected");
assert!(
error.to_string().contains("not_a_parameter"),
"the error must name the offending parameter, got: {error}"
);
}
mod user_defined_commands {
use rustis::{
client::{Client, PreparedCommand, prepare_command},
resp::cmd,
};
use serde::Serialize;
trait MyCommands<'a> {
#[must_use]
fn myget(self, key: impl Serialize) -> PreparedCommand<'a, Self, String>
where
Self: Sized,
{
prepare_command(self, cmd("MYGET").key(key))
}
}
impl<'a> MyCommands<'a> for &'a Client {}
async fn the_new_command_is_used_like_a_built_in(client: &Client) -> rustis::Result<()> {
let _: String = client.myget("key").await?;
Ok(())
}
}
async fn a_generic_command_is_queued_by_its_own_name(client: &Client) -> Result<()> {
let mut pipeline = client.create_pipeline();
pipeline.queue_command(cmd("SET").key("key").arg("value"));
pipeline.forget_command(cmd("SET").key("key2").arg("value"));
let _: (String,) = pipeline.execute().await?;
let mut transaction = client.create_transaction();
transaction.queue_command(cmd("SET").key("key").arg("value"));
transaction.forget_command(cmd("SET").key("key2").arg("value"));
let _: (String,) = transaction.execute().await?;
Ok(())
}