Files
appks/immediate/typing.rs
T
2026-06-07 11:30:56 +08:00

72 lines
1.9 KiB
Rust

use uuid::Uuid;
use crate::cache::redis::AppRedis;
use crate::error::{AppError, AppResult};
use crate::service::im::util::{TYPING_PREFIX, TYPING_TTL_SECS};
use ::redis::Cmd;
pub fn set_typing(
redis: &AppRedis,
channel_id: Uuid,
thread_id: Option<Uuid>,
user_id: Uuid,
) -> AppResult<()> {
let key = typing_key(channel_id, thread_id, user_id);
let mut conn = redis.get_connection()?;
Cmd::new()
.arg("SETEX")
.arg(&key)
.arg(TYPING_TTL_SECS as u64)
.arg("1")
.query::<()>(&mut *conn.inner_mut())?;
Ok(())
}
pub fn clear_typing(
redis: &AppRedis,
channel_id: Uuid,
thread_id: Option<Uuid>,
user_id: Uuid,
) -> AppResult<()> {
let key = typing_key(channel_id, thread_id, user_id);
let mut conn = redis.get_connection()?;
Cmd::new()
.arg("DEL")
.arg(&key)
.query::<()>(&mut *conn.inner_mut())?;
Ok(())
}
pub fn get_typing_users(
redis: &AppRedis,
channel_id: Uuid,
thread_id: Option<Uuid>,
) -> AppResult<Vec<Uuid>> {
let pattern = match thread_id {
Some(tid) => format!("{TYPING_PREFIX}{channel_id}:{tid}:*"),
None => format!("{TYPING_PREFIX}{channel_id}:*"),
};
let mut conn = redis.get_connection()?;
let keys: Vec<String> = Cmd::new()
.arg("KEYS")
.arg(&pattern)
.query(&mut *conn.inner_mut())
.map_err(AppError::Redis)?;
let mut ids = Vec::with_capacity(keys.len());
for key in &keys {
if let Some(part) = key.rsplit(':').next()
&& let Ok(uid) = part.parse::<Uuid>()
{
ids.push(uid);
}
}
Ok(ids)
}
fn typing_key(channel_id: Uuid, thread_id: Option<Uuid>, user_id: Uuid) -> String {
match thread_id {
Some(tid) => format!("{TYPING_PREFIX}{channel_id}:{tid}:{user_id}"),
None => format!("{TYPING_PREFIX}{channel_id}:{user_id}"),
}
}