目的
RustのRedisクレートはいい感じに型変換をしてくれます。ただし最近導入されたストリーム型は面倒な形をしているので注意が必要です。
プログラム
簡単な例
queryメソッドの戻り値をbindする型で変換してくれます。
Cargo.toml
[package]
name = "redis_test"
version = "0.1.0"
edition = "2018"
[dependencies]
r2d2_redis = "^0.12"
main.rs
use std::error::Error;
use std::ops::DerefMut;
type RedisConn = r2d2_redis::r2d2::PooledConnection<r2d2_redis::RedisConnectionManager>;
fn get_conn() -> Result<RedisConn, Box<dyn Error>>{
let manager = r2d2_redis::RedisConnectionManager::new("redis://localhost:6379")?;
let pool = r2d2_redis::r2d2::Pool::builder().max_size(2).build(manager)?;
Ok(pool.get()?)
}
fn main() -> Result<(), Box<dyn Error>>{
let mut conn = get_conn()?;
r2d2_redis::redis::cmd("SET").arg("aaa").arg("1").query(conn.deref_mut())?;
let res: String = r2d2_redis::redis::cmd("GET").arg("aaa").query(conn.deref_mut())?;
println!("{:?}", res);
let res: i64 = r2d2_redis::redis::cmd("GET").arg("aaa").query(conn.deref_mut())?;
println!("{:?}", res);
}
結果
"1"
1
pipe
パイプを使うことで複数の値を取得することができます。
main.rs
fn main() -> Result<(), Box<dyn Error>>{
let mut conn = get_conn()?;
r2d2_redis::redis::pipe()
.cmd("DEL").arg("aaa")
.cmd("SET").arg("aaa").arg("1")
.cmd("DEL").arg("bbb")
.cmd("SET").arg("bbb").arg("2")
.query(conn.deref_mut())?;
let res: (String, i64) = r2d2_redis::redis::pipe()
.cmd("GET").arg("aaa")
.cmd("GET").arg("bbb")
.query(conn.deref_mut())?;
println!("{:?}", res);
}
結果
("1", 1)
List
配列を回して引数を追加することもできます。
main.rs
fn main() -> Result<(), Box<dyn Error>>{
let mut conn = get_conn()?;
let args = vec![1,2,3];
let mut pipe = r2d2_redis::redis::pipe();
let cmd = pipe
.cmd("DEL").arg("aaa")
.cmd("RPUSH").arg("aaa");
for i in args.iter() {
cmd.arg(*i);
}
cmd.query(conn.deref_mut())?;
let list: Vec<i64> = r2d2_redis::redis::cmd("LRANGE")
.arg("aaa").arg(0).arg(-1).query(conn.deref_mut())?;
println!("{:?}", list);
}
結果
[1, 2, 3]
Hash
HashMapに変換することができます。
main.rs
use std::collections::HashMap;
fn main() -> Result<(), Box<dyn Error>>{
let mut conn = get_conn()?;
r2d2_redis::redis::pipe()
.cmd("DEL").arg("aaa")
.cmd("HSET").arg("aaa").arg("a").arg("1")
.cmd("HSET").arg("aaa").arg("b").arg("2")
.query(conn.deref_mut())?;
let res: HashMap<String, String> = r2d2_redis::redis::cmd("HGETALL")
.arg("aaa").query(conn.deref_mut())?;
println!("{:?}", res);
}
結果
{"a": "1", "b": "2"}
Stream
Vecが重複しているように見えますが、こうしないと正しく取得できませんでした。
main.rs
fn main() -> Result<(), Box<dyn Error>>{
let mut conn = get_conn()?;
r2d2_redis::redis::pipe()
.cmd("DEL").arg("aaa")
.cmd("DEL").arg("bbb")
.cmd("XADD").arg("aaa").arg("*").arg("a").arg("1").arg("b").arg("2")
.cmd("XADD").arg("bbb").arg("*").arg("c").arg("1").arg("d").arg("2")
.cmd("XADD").arg("aaa").arg("*").arg("a").arg("3").arg("b").arg("4")
.cmd("XADD").arg("bbb").arg("*").arg("c").arg("3").arg("d").arg("4")
.query(conn.deref_mut())?;
let res: Vec<Vec<(String, Vec<Vec<(String, HashMap<String, String>)>>)>> = r2d2_redis::redis::cmd("XREAD")
.arg("COUNT").arg("2").arg("STREAMS").arg("aaa").arg("bbb").arg("0").arg("0").query(conn.deref_mut())?;
println!("{:?}", res);
}
結果
[
[("aaa", [[("1574640845410-0", {"a": "1", "b": "2"})], [("1574640845410-1", {"a": "3", "b": "4"})]])],
[("bbb", [[("1574640845410-0", {"d": "2", "c": "1"})], [("1574640845410-1", {"c": "3", "d": "4"})]])]
]