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(buf: &mut ByteBuffer, 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( buf: &ByteBuffer, offset: usize, caps: &Vec, ) -> Result where Self: Sized; fn parse_from_request( buf: &ByteBuffer, caps: &Vec, ) -> Result where Self: Sized, { if buf.at::(0)? != SENTINEL { return Err(ZError::INVALID_RESPONSE); } Ok(Self::parse(&buf, 16, &caps)?) } fn serialize( &self, buf: &mut ByteBuffer, offset: usize, caps: &mut Vec, ) -> Result; fn serialize_as_request( &self, request_id: u64, buf: &mut ByteBuffer, caps: &mut Vec, ) -> Result { 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( _buf: &ByteBuffer, _offset: usize, _caps: &Vec, ) -> Result where Self: Sized, { todo!() } fn serialize( &self, _buf: &mut ByteBuffer, _offset: usize, _caps: &mut Vec, ) -> Result { todo!() } }