use crate::buffer::ByteBuffer; use alloc::vec::Vec; use mammoth::zion::z_cap_t; use mammoth::zion::ZError; pub const MESSAGE_IDENT: u32 = 0x33441122; pub const MESSAGE_HEADER_SIZE: usize = 24; // 4x uint32, 1x uint64 const SENTINEL: u32 = 0xBEEFDEAD; const SERIALIZE_HEADER_SIZE: u32 = 0x10; pub fn field_offset(offset: usize, field_index: usize) -> usize { offset + MESSAGE_HEADER_SIZE + (8 * field_index) } pub fn serialize_error<const N: usize>(buf: &mut ByteBuffer<N>, err: ZError) { buf.write_at(0, SENTINEL) .expect("Failed to serialize SENTINEL"); buf.write_at(4, SERIALIZE_HEADER_SIZE) .expect("Failed to serialize size"); buf.write_at(8, err as u64) .expect("Failed to serialize error"); } pub trait YunqMessage { fn parse<const N: usize>( buf: &ByteBuffer<N>, offset: usize, caps: &Vec<z_cap_t>, ) -> Result<Self, ZError> where Self: Sized; fn parse_from_request<const N: usize>( buf: &ByteBuffer<N>, caps: &Vec<z_cap_t>, ) -> Result<Self, ZError> where Self: Sized, { if buf.at::<u32>(0)? != SENTINEL { return Err(ZError::INVALID_RESPONSE); } Ok(Self::parse(&buf, 16, &caps)?) } fn serialize<const N: usize>( &self, buf: &mut ByteBuffer<N>, offset: usize, caps: &mut Vec<z_cap_t>, ) -> Result<usize, ZError>; fn serialize_as_request<const N: usize>( &self, request_id: u64, buf: &mut ByteBuffer<N>, caps: &mut Vec<z_cap_t>, ) -> Result<usize, ZError> { buf.write_at(0, SENTINEL)?; buf.write_at(8, request_id as u64)?; let length = self.serialize(buf, 16, caps)?; buf.write_at(4, (16 + length) as u32)?; Ok(length + 16) } } pub struct Empty {} impl YunqMessage for Empty { fn parse<const N: usize>( _buf: &ByteBuffer<N>, _offset: usize, _caps: &Vec<z_cap_t>, ) -> Result<Self, ZError> where Self: Sized, { todo!() } fn serialize<const N: usize>( &self, _buf: &mut ByteBuffer<N>, _offset: usize, _caps: &mut Vec<z_cap_t>, ) -> Result<usize, ZError> { todo!() } }