use redis::{Commands, FromRedisValue, RedisResult, ToRedisArgs};
use tracing::{debug, error};
#[allow(unused_imports)]
use crate::core::result::{RedsumerError, RedsumerResult};
fn produce_from_map<C, K, M, ID>(c: &mut C, key: K, map: M) -> RedisResult<ID>
where
C: Commands,
K: ToRedisArgs,
M: ToRedisArgs,
ID: FromRedisValue,
{
match c.xadd_map(key, "*", map) {
Ok(id) => {
debug!("Message produced successfully");
Ok(id)
}
Err(e) => {
error!("Error producing message: {:?}", e);
Err(e)
}
}
}
fn produce_from_items<C, K, F, V, ID>(c: &mut C, key: K, items: &[(F, V)]) -> RedisResult<ID>
where
C: Commands,
K: ToRedisArgs,
F: ToRedisArgs,
V: ToRedisArgs,
ID: FromRedisValue,
{
match c.xadd(key, "*", items) {
Ok(id) => {
debug!("Message produced successfully");
Ok(id)
}
Err(e) => {
error!("Error producing message: {:?}", e);
Err(e)
}
}
}
pub trait ProducerCommands {
fn produce_from_map<K, M>(&mut self, key: K, map: M) -> RedsumerResult<String>
where
K: ToRedisArgs,
M: ToRedisArgs;
fn produce_from_items<K, F, V>(&mut self, key: K, items: &[(F, V)]) -> RedsumerResult<String>
where
K: ToRedisArgs,
F: ToRedisArgs,
V: ToRedisArgs;
}
impl<C> ProducerCommands for C
where
C: Commands,
{
fn produce_from_map<K, M>(&mut self, key: K, map: M) -> RedsumerResult<String>
where
K: ToRedisArgs,
M: ToRedisArgs,
{
produce_from_map(self, key, map)
}
fn produce_from_items<K, F, V>(&mut self, key: K, items: &[(F, V)]) -> RedsumerResult<String>
where
K: ToRedisArgs,
F: ToRedisArgs,
V: ToRedisArgs,
{
produce_from_items(self, key, items)
}
}
#[cfg(test)]
mod test_produce_from_map {
use std::collections::BTreeMap;
use redis::{cmd, ErrorKind, Value};
use redis_test::{MockCmd, MockRedisConnection};
use super::*;
#[test]
fn test_produce_from_map_ok() {
let key: &str = "my-key";
let mut map: BTreeMap<&str, &str> = BTreeMap::new();
map.insert("field", "value");
let mut conn: MockRedisConnection =
MockRedisConnection::new(vec![MockCmd::new::<_, Value>(
cmd("XADD").arg(key).arg("*").arg(map.to_owned()),
Ok(Value::SimpleString("1-0".to_string())),
)]);
let result: RedsumerResult<String> = conn.produce_from_map(key, map);
assert!(result.is_ok());
}
#[test]
fn test_produce_from_map_error() {
let key: &str = "my-key";
let mut map: BTreeMap<&str, &str> = BTreeMap::new();
map.insert("field", "value");
let mut conn: MockRedisConnection =
MockRedisConnection::new(vec![MockCmd::new::<_, Value>(
cmd("XADD").arg(key).arg("*").arg(map.to_owned()),
Err(RedsumerError::from((
ErrorKind::ResponseError,
"XADD Error",
"XADD command failed".to_string(),
))),
)]);
let result: RedsumerResult<String> = conn.produce_from_map(key, map);
assert!(result.is_err());
}
}
#[cfg(test)]
mod test_produce_from_items {
use redis::{cmd, ErrorKind, Value};
use redis_test::{MockCmd, MockRedisConnection};
use super::*;
#[test]
fn test_produce_from_items_ok() {
let key: &str = "my-key";
let items: Vec<(&str, u8)> = vec![("number", 3), ("double", 6)];
let mut conn: MockRedisConnection =
MockRedisConnection::new(vec![MockCmd::new::<_, Value>(
cmd("XADD").arg(key).arg("*").arg(&items),
Ok(Value::SimpleString("1-0".to_string())),
)]);
let result: RedsumerResult<String> = conn.produce_from_items(key, &items);
assert!(result.is_ok());
}
#[test]
fn test_produce_from_items_error() {
let key: &str = "my-key";
let items: Vec<(&str, &str)> = vec![("field", "value")];
let mut conn: MockRedisConnection =
MockRedisConnection::new(vec![MockCmd::new::<_, Value>(
cmd("XADD").arg(key).arg("*").arg(&items),
Err(RedsumerError::from((
ErrorKind::ResponseError,
"XADD Error",
"XADD command failed".to_string(),
))),
)]);
let result: RedsumerResult<String> = conn.produce_from_items(key, &items);
assert!(result.is_err());
}
}