use capnp::message::{Builder, HeapAllocator}; use capnp::message::{ReaderOptions, TypedReader}; use capnp::serialize::{self, SliceSegments}; use capnp::traits::Owned; use churn_domain::{Agent, LogEvent}; mod models_capnp; pub trait CapnpPackExt { type Return; fn serialize_capnp(&self) -> Vec; fn deserialize_capnp(content: &Vec) -> anyhow::Result; fn capnp_to_string(builder: &Builder) -> Vec { serialize::write_message_to_words(builder) } fn string_to_capnp(content: &Vec) -> TypedReader where S: Owned, { let log_event = serialize::read_message_from_flat_slice(&mut content.as_slice(), ReaderOptions::new()) .unwrap(); log_event.into_typed::() } } impl CapnpPackExt for LogEvent { type Return = Self; fn serialize_capnp(&self) -> Vec { let mut builder = Builder::new_default(); let mut log_event = builder.init_root::(); log_event.set_id(&self.id.to_string()); log_event.set_author(&self.author); log_event.set_content(&self.content); log_event.set_datetime(self.timestamp.timestamp()); Self::capnp_to_string(&builder) } fn deserialize_capnp(content: &Vec) -> anyhow::Result { let log_event = Self::string_to_capnp::(content); let log_event = log_event.get()?; Ok(Self { id: uuid::Uuid::parse_str(log_event.get_id()?)?, author: log_event.get_author()?.into(), content: log_event.get_content()?.into(), timestamp: chrono::DateTime::::from_utc( chrono::NaiveDateTime::from_timestamp_opt(log_event.get_datetime(), 0).unwrap(), chrono::Utc, ), }) } } impl CapnpPackExt for Agent { type Return = Self; fn serialize_capnp(&self) -> Vec { let mut builder = Builder::new_default(); let mut item = builder.init_root::(); item.set_name(&self.name); Self::capnp_to_string(&builder) } fn deserialize_capnp(content: &Vec) -> anyhow::Result { let item = Self::string_to_capnp::(content); let item = item.get()?; Ok(Self { name: item.get_name()?.into(), }) } }