use std::collections::{HashMap, VecDeque}; use anyhow::anyhow; use tokio::sync::RwLock; pub struct MessageHistory { map: RwLock>>, maxlen: usize } impl MessageHistory { pub fn new(maxlen: usize) -> MessageHistory { MessageHistory { map: RwLock::new(HashMap::new()), maxlen } } pub fn max_len(&self) -> usize { self.maxlen } pub async fn last_msg(&self, user: &str) -> Option { let map = self.map.read().await; map.get(user).and_then(|d| d.get(0)).map(|s| s.to_string()) } pub async fn last_msgs(&self, user: &str, count: usize) -> Option> { let map = self.map.read().await; if let Some(deque) = map.get(user) { let count = if deque.len() < count { deque.len() } else {count}; Some(deque.range(..count).rev().map(ToString::to_string).collect()) } else { None } } pub async fn add_message(&self, user: &str, message: &str) { let mut map = self.map.write().await; if let Some(deque) = map.get_mut(user) { if deque.len() == self.maxlen { deque.remove(deque.len()-1); } deque.push_front(message.to_string()); } else { let mut deque = VecDeque::with_capacity(self.maxlen); deque.push_front(message.to_string()); map.insert(user.to_string(), deque); } } }