lib-nested/nested/src/vec/vec2json.rs

110 lines
2.9 KiB
Rust

use {
crate::{
core::{Observer, OuterViewPort},
vec::{VecBuffer, VecDiff},
},
async_std::{
io::{Read, ReadExt},
stream::StreamExt,
},
serde::{de::DeserializeOwned, Serialize},
std::sync::RwLock,
std::{io::Write, sync::Arc},
};
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct VecJsonWriter<T, W>
where
T: Clone + Send + Sync + 'static,
W: Write + Send + Sync,
{
data: Option<Arc<RwLock<Vec<T>>>>,
out: RwLock<W>,
}
impl<T> OuterViewPort<RwLock<Vec<T>>>
where
T: Clone + Serialize + Send + Sync + 'static,
{
pub fn serialize_json<W: Write + Send + Sync + 'static>(
&self,
out: W,
) -> Arc<RwLock<VecJsonWriter<T, W>>> {
let writer = Arc::new(RwLock::new(VecJsonWriter {
data: None,
out: RwLock::new(out),
}));
self.add_observer(writer.clone());
writer
}
}
impl<T, W> Observer<RwLock<Vec<T>>> for VecJsonWriter<T, W>
where
T: Clone + Serialize + Send + Sync + 'static,
W: Write + Send + Sync,
{
fn reset(&mut self, view: Option<Arc<RwLock<Vec<T>>>>) {
self.data = view;
self.out
.write()
.unwrap()
.write(
&serde_json::to_string(&VecDiff::<T>::Clear)
.unwrap()
.as_bytes(),
)
.expect("");
self.out.write().unwrap().write(b"\n").expect("");
if let Some(data) = self.data.as_ref() {
for x in data.read().unwrap().iter() {
self.out
.write()
.unwrap()
.write(&serde_json::to_string(&VecDiff::Push(x)).unwrap().as_bytes())
.expect("");
self.out.write().unwrap().write(b"\n").expect("");
}
}
self.out.write().unwrap().flush().expect("");
}
fn notify(&mut self, diff: &VecDiff<T>) {
self.out
.write()
.unwrap()
.write(serde_json::to_string(diff).unwrap().as_bytes())
.expect("");
self.out.write().unwrap().write(b"\n").expect("");
self.out.write().unwrap().flush().expect("");
}
}
impl<T> VecBuffer<T>
where
T: DeserializeOwned + Clone + Send + Sync + 'static,
{
pub async fn from_json<R: Read + async_std::io::Read + Unpin>(&mut self, read: R) {
let mut bytes = read.bytes();
let mut s = String::new();
while let Some(Ok(b)) = bytes.next().await {
match b {
b'\n' => {
if s.len() > 0 {
let diff =
serde_json::from_str::<VecDiff<T>>(&s).expect("error parsing json");
self.apply_diff(diff);
s.clear();
}
}
c => {
s.push(c as char);
}
}
}
}
}