use bitflags::bitflags;
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MsgKind {
Request = 0x01,
Response = 0x02,
StreamChunk = 0x03,
StreamEnd = 0x04,
Cancel = 0x05,
Log = 0x06,
}
impl TryFrom<u8> for MsgKind {
type Error = u8;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0x01 => Ok(Self::Request),
0x02 => Ok(Self::Response),
0x03 => Ok(Self::StreamChunk),
0x04 => Ok(Self::StreamEnd),
0x05 => Ok(Self::Cancel),
0x06 => Ok(Self::Log),
other => Err(other),
}
}
}
bitflags! {
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct MsgFlags: u8 {
const MORE = 1 << 0;
}
}
#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
#[repr(C)]
pub struct VirtqMsgHeader {
pub kind: u8,
pub flags: u8,
pub req_id: u16,
pub payload_len: u32,
}
impl VirtqMsgHeader {
pub const SIZE: usize = core::mem::size_of::<Self>();
pub const fn new(kind: MsgKind, req_id: u16, payload_len: u32) -> Self {
Self {
kind: kind as u8,
flags: 0,
req_id,
payload_len,
}
}
pub const fn with_flags(kind: MsgKind, flags: MsgFlags, req_id: u16, payload_len: u32) -> Self {
Self {
kind: kind as u8,
flags: flags.bits(),
req_id,
payload_len,
}
}
pub fn msg_kind(&self) -> Result<MsgKind, u8> {
MsgKind::try_from(self.kind)
}
pub fn msg_flags(&self) -> MsgFlags {
MsgFlags::from_bits_truncate(self.flags)
}
pub const fn has_more(&self) -> bool {
self.flags & MsgFlags::MORE.bits() != 0
}
}