You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
yuurei/src/state/local/mod.rs

129 lines
2.6 KiB

//! Handles updating posts
use super::*;
use std::{
sync::Arc,
};
use tokio::{
sync::{
RwLock,
watch,
},
};
mod karada;
pub use karada::*;
mod delta;
pub use delta::*;
mod work;
pub use work::*;
//mod host;
//pub use host::*;
mod error;
pub use error::Error as LocalError;
/// An open, as yet unfinied post
#[derive(Debug)]
pub struct Imouto
{
id: identity::PostID,
user: identity::User,
title: Option<String>,
karada: Karada,
worker: Kokoro,
timestamp: post::PostTimestamp, //Note that `closed` should always be `None` in `Imouto`. We use this for post lifetimes and such
}
use suspend::{
Suspendable,
SuspendStream,
};
#[async_trait]
impl Suspendable for Imouto
{
async fn suspend<S: SuspendStream +Send+Sync + ?Sized>(self, into: &mut S) -> Result<(), suspend::Error>
{
let mut output = suspend::Object::new();
output.insert("id", self.id);
output.insert("user", self.user);
output.insert("title", self.title);
output.insert("body", self.worker.into_suspended().await); // consume worker if possible
//output.insert("hash", self.hash);
output.insert("timestamp", self.timestamp);
into.set_object(output).await
}
async fn load<S: SuspendStream +Send+Sync+ ?Sized>(from: &mut S) -> Result<Self, suspend::Error>
{
let mut input = from.get_object().await?.ok_or(suspend::Error::BadObject)?;
macro_rules! get {
($name:literal) => {
input.try_get($name).ok_or_else(|| suspend::Error::MissingObject(std::borrow::Cow::Borrowed($name)))?
};
}
let id = get!("id");
let user = get!("user");
let title = get!("title");
let body = get!("body");
//let hash = get!("hash");
let timestamp = get!("timestamp");
let (karada, worker) = {
let mut kokoro = Kokoro::from_suspended(body);
(kokoro.spawn().unwrap(), kokoro)
};
Ok(Self {
id,
user,
title,
karada,
worker,
//hash,
timestamp,
})
}
}
#[cfg(test)]
mod tests
{
use super::*;
#[tokio::test]
async fn basic_ser()
{
let mut output = suspend::MemorySuspendStream::new();
let mut lolis = std::iter::repeat_with(|| {
let (karada, kokoro) = {
let mut kokoro = Kokoro::new();
(kokoro.spawn().unwrap(), kokoro)
};
Imouto {
id: identity::PostID::new(),
user: Default::default(),
title: None,
karada,
worker: kokoro,
timestamp: post::PostTimestamp::new()
}
});
let imouto = lolis.next().unwrap();
imouto.suspend(&mut output).await.expect("Suspension failed");
let imouto2 = lolis.next().unwrap();
let imouto3 = Imouto::load(&mut output).await.expect("Load failed");
assert_eq!(imouto2.karada.body(), imouto3.karada.body());
}
}