use capnp::message::{Builder, HeapAllocator}; use capnp::message::{ReaderOptions, TypedReader}; use capnp::serialize::{self, BufferSegments}; use capnp::traits::Owned; use churn_domain::{Agent, Lease, LogEvent}; mod models_capnp; pub trait CapnpPackExt { type Return; fn serialize_capnp(&self) -> Vec; fn deserialize_capnp(content: &[u8]) -> anyhow::Result; fn capnp_to_string(builder: &Builder) -> Vec { serialize::write_message_to_words(builder) } fn string_to_capnp(mut content: &[u8]) -> TypedReader, S> where S: Owned, { let log_event = serialize::read_message_from_flat_slice(&mut content, 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: &[u8]) -> 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()?.to_str()?)?, author: log_event.get_author()?.to_string()?, content: log_event.get_content()?.to_string()?, 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: &[u8]) -> anyhow::Result { let item = Self::string_to_capnp::(content); let item = item.get()?; Ok(Self { name: item.get_name()?.to_string()?, }) } } impl CapnpPackExt for Lease { type Return = Self; fn serialize_capnp(&self) -> Vec { let mut builder = Builder::new_default(); let mut item = builder.init_root::(); item.set_id(&self.id.to_string()); item.set_lease(&self.lease.to_string()); Self::capnp_to_string(&builder) } fn deserialize_capnp(content: &[u8]) -> anyhow::Result { let item = Self::string_to_capnp::(content); let item = item.get()?; Ok(Self { id: uuid::Uuid::parse_str(item.get_id()?.to_str()?)?, lease: uuid::Uuid::parse_str(item.get_lease()?.to_str()?)?, }) } }