parent
31ecef8954
commit
0a6c1304dc
@ -1,2 +1 @@
|
||||
use super::*;
|
||||
|
||||
//! Services
|
||||
|
@ -1,14 +0,0 @@
|
||||
use super::*;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use super::*;
|
||||
|
||||
use user::{User, UserID};
|
||||
use post::Post;
|
||||
|
||||
/// Contains all posts
|
||||
#[derive(Debug)]
|
||||
pub struct State
|
||||
{
|
||||
users: HashSet<User>,
|
||||
posts: HashMap<UserID, MaybeVec<Post>>
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
//! Frozen, serialisable state
|
||||
use super::*;
|
||||
use futures::prelude::*;
|
||||
|
||||
/// An immutable image of `State`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Freeze
|
||||
{
|
||||
users: HashSet<User>,
|
||||
posts: Vec<(UserID, Post)>,
|
||||
}
|
||||
|
||||
impl Freeze
|
||||
{
|
||||
/// Create a `State` from this freeze
|
||||
///
|
||||
/// # Notes
|
||||
/// This clones all post and user data, to perform this operation without cloning, use `into_state`.
|
||||
pub fn unfreeze(&self) -> State
|
||||
{
|
||||
let users: HashMap<UserID, RwLock<User>> = self.users
|
||||
.iter()
|
||||
.map(|x| (*x.id(), RwLock::new(x.clone()))).collect();
|
||||
let mut posts: HashMap<UserID, MaybeVec<RwLock<Post>>> = HashMap::with_capacity(users.len());
|
||||
|
||||
for (id, post) in self.posts.iter()
|
||||
{
|
||||
posts.entry(*id).or_insert_with(move || MaybeVec::new()).push(RwLock::new(post.clone()));
|
||||
}
|
||||
|
||||
State(Arc::new(Inner{posts: RwLock::new( Posts {
|
||||
users,
|
||||
posts
|
||||
})}))
|
||||
}
|
||||
|
||||
/// Consume into a new `State`.
|
||||
pub fn into_state(self) -> State
|
||||
{
|
||||
State::from_freeze(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl State
|
||||
{
|
||||
/// Create a serialisable image from this state
|
||||
pub async fn freeze(&self) -> Freeze
|
||||
{
|
||||
let posts = self.0.posts.read().await;
|
||||
let users: HashSet<User> = {
|
||||
stream::iter(posts.users.iter())
|
||||
.then(|(_, x)| async move { x.read().await })
|
||||
.map(|x| x.clone()).collect().await
|
||||
};
|
||||
let posts: Vec<_> = {
|
||||
stream::iter(posts.posts.iter()
|
||||
.map(|(x, y)| y.into_iter().map(move |z| (x, z))).flatten())
|
||||
.then(|x| async move { (x.0, x.1.read().await) })
|
||||
.map(|(&id, post)| (id, post.clone())).collect().await
|
||||
};
|
||||
|
||||
Freeze {users, posts}
|
||||
}
|
||||
|
||||
/// Create `State` from this image
|
||||
pub fn from_freeze(freeze: Freeze) -> Self
|
||||
{
|
||||
let users: HashMap<UserID, RwLock<User>> = freeze.users
|
||||
.into_iter()
|
||||
.map(|x| (*x.id(), RwLock::new(x))).collect();
|
||||
let mut posts: HashMap<UserID, MaybeVec<RwLock<Post>>> = HashMap::with_capacity(users.len());
|
||||
|
||||
for (id, post) in freeze.posts.into_iter()
|
||||
{
|
||||
posts.entry(id).or_insert_with(move || MaybeVec::new()).push(RwLock::new(post));
|
||||
}
|
||||
|
||||
Self(Arc::new(Inner{posts: RwLock::new( Posts {
|
||||
users,
|
||||
posts
|
||||
})}))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Freeze> for State
|
||||
{
|
||||
#[inline] fn from(from: Freeze) -> Self
|
||||
{
|
||||
Self::from_freeze(from)
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
use super::*;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
use user::{User, UserID};
|
||||
use post::Post;
|
||||
|
||||
mod freeze;
|
||||
pub use freeze::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Posts
|
||||
{
|
||||
users: HashMap<UserID, RwLock<User>>,
|
||||
posts: HashMap<UserID, MaybeVec<RwLock<Post>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Inner
|
||||
{
|
||||
posts: RwLock<Posts>,
|
||||
}
|
||||
|
||||
/// Contains all posts and users
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct State(Arc<Inner>);
|
Loading…
Reference in new issue