use super::*; use std::collections::{HashMap, HashSet}; use std::sync::Arc; use tokio::sync::{ RwLock, RwLockReadGuard, }; use user::{User, UserID}; use post::Post; mod freeze; pub use freeze::*; #[derive(Debug)] struct Posts { users: HashMap>, posts: HashMap>>, } /// A read lock over all posts and users #[derive(Debug)] pub struct PostsLock<'a>(RwLockReadGuard<'a, Posts>); #[derive(Debug)] struct Inner { posts: RwLock, } /// Contains all posts and users #[derive(Debug, Clone)] pub struct State(Arc); impl State { /// Create a new empty state pub fn new() -> Self { Self(Arc::new( Inner { posts: RwLock::new(Posts { users: HashMap::new(), posts: HashMap::new(), }) } )) } /// Read lock over all posts and users pub async fn posts(&self) -> PostsLock<'_> { PostsLock(self.0.posts.read().await) } } impl<'a> PostsLock<'a> { /// An iterator over all users in this state pub fn users<'b>(&'b self) -> impl Iterator> + ExactSizeIterator + 'b { self.0.users.iter().map(|(_, u)| u) } /// An iterator over all posts for this user /// /// # Notes /// If this user does not exist, the returned iterator will yield 0 items. pub fn posts_for<'b>(&'b self, user: &UserID) -> impl Iterator> + ExactSizeIterator + 'b where 'a: 'b { MaybeIter::from(self.0.posts.get(user).map(|x| x.iter())) } /// An iterator over all posts in the state pub fn all_posts<'b>(&'b self) -> impl Iterator> + 'b where 'a: 'b { self.0.posts.iter().map(|(_, p)| p.iter()).flatten() } }