use serde::{Deserialize, Serialize};
use versionize::{VersionMap, Versionize, VersionizeResult};
use versionize_derive::Versionize;
use virtio_queue::QueueState;
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, Versionize)]
pub struct QueueStateSer {
pub max_size: u16,
pub next_avail: u16,
pub next_used: u16,
pub event_idx_enabled: bool,
pub size: u16,
pub ready: bool,
pub desc_table: u64,
pub avail_ring: u64,
pub used_ring: u64,
}
impl From<&QueueStateSer> for QueueState {
fn from(state: &QueueStateSer) -> Self {
QueueState {
max_size: state.max_size,
next_avail: state.next_avail,
next_used: state.next_used,
event_idx_enabled: state.event_idx_enabled,
size: state.size,
ready: state.ready,
desc_table: state.desc_table,
avail_ring: state.avail_ring,
used_ring: state.used_ring,
}
}
}
impl From<&QueueState> for QueueStateSer {
fn from(state: &QueueState) -> Self {
QueueStateSer {
max_size: state.max_size,
next_avail: state.next_avail,
next_used: state.next_used,
event_idx_enabled: state.event_idx_enabled,
size: state.size,
ready: state.ready,
desc_table: state.desc_table,
avail_ring: state.avail_ring,
used_ring: state.used_ring,
}
}
}
impl Default for QueueStateSer {
fn default() -> Self {
QueueStateSer::from(&QueueState::default())
}
}
#[cfg(test)]
mod tests {
use super::*;
use virtio_queue::{Error, Queue};
#[test]
fn test_state_ser() {
const SOME_VALUE: u16 = 16;
let state = QueueState {
max_size: SOME_VALUE * 2,
next_avail: SOME_VALUE - 1,
next_used: SOME_VALUE + 1,
event_idx_enabled: false,
size: SOME_VALUE,
ready: true,
desc_table: SOME_VALUE as u64,
avail_ring: SOME_VALUE as u64 * 2,
used_ring: SOME_VALUE as u64 * 4,
};
let ser_state = QueueStateSer::from(&state);
let state_from_ser = QueueState::from(&ser_state);
assert_eq!(state, state_from_ser);
let default_queue_state_ser = QueueStateSer::default();
assert_eq!(
QueueState::from(&default_queue_state_ser),
QueueState::default()
);
}
#[test]
fn test_ser_with_len_zero() {
let queue_ser = QueueStateSer {
max_size: 16,
next_avail: 0,
next_used: 0,
event_idx_enabled: false,
size: 0,
ready: true,
desc_table: 0,
avail_ring: 256,
used_ring: 276,
};
let queue_state = QueueState::from(&queue_ser);
let err = Queue::try_from(queue_state).unwrap_err();
assert_eq!(err, Error::InvalidSize);
}
}