|
|
|
@ -1,7 +1,10 @@
|
|
|
|
|
use super::*;
|
|
|
|
|
use std::collections::{HashMap, HashSet};
|
|
|
|
|
use std::sync::Arc;
|
|
|
|
|
use tokio::sync::RwLock;
|
|
|
|
|
use tokio::sync::{
|
|
|
|
|
RwLock,
|
|
|
|
|
RwLockReadGuard,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
use user::{User, UserID};
|
|
|
|
|
use post::Post;
|
|
|
|
@ -16,6 +19,10 @@ struct Posts
|
|
|
|
|
posts: HashMap<UserID, MaybeVec<RwLock<Post>>>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A read lock over all posts and users
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub struct PostsLock<'a>(RwLockReadGuard<'a, Posts>);
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
struct Inner
|
|
|
|
|
{
|
|
|
|
@ -25,3 +32,50 @@ struct Inner
|
|
|
|
|
/// Contains all posts and users
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub struct State(Arc<Inner>);
|
|
|
|
|
|
|
|
|
|
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<Item = &'b RwLock<User>> + 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<Item= &'b RwLock<Post>> + 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<Item= &'b RwLock<Post>> + 'b
|
|
|
|
|
where 'a: 'b
|
|
|
|
|
{
|
|
|
|
|
self.0.posts.iter().map(|(_, p)| p.iter()).flatten()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|