use alloc::vec::Vec;
use zerodds_cdr::{BufferReader, BufferWriter, DecodeError, EncodeError, Endianness};
use crate::priority::Priority;
pub const RT_CORBA_PRIORITY_SC_ID: u32 = 10;
pub fn encode_priority_context(
priority: Priority,
endianness: Endianness,
) -> Result<Vec<u8>, EncodeError> {
let mut w = BufferWriter::new(endianness);
w.write_u8(match endianness {
Endianness::Big => 0,
Endianness::Little => 1,
})?;
w.write_u16(priority.value() as u16)?;
Ok(w.into_bytes())
}
pub fn decode_priority_context(data: &[u8]) -> Result<Priority, DecodeError> {
let bo = *data.first().ok_or(DecodeError::UnexpectedEof {
needed: 1,
offset: 0,
})?;
let e = if bo == 0 {
Endianness::Big
} else {
Endianness::Little
};
let mut r = BufferReader::new(data, e);
r.read_u8()?; let raw = r.read_u16()? as i16;
Priority::new(raw).ok_or(DecodeError::InvalidEnum {
kind: "RTCorbaPriority out of range",
value: u32::from(raw as u16),
})
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::panic)]
mod tests {
use super::*;
#[test]
fn sc_id_is_ten() {
assert_eq!(RT_CORBA_PRIORITY_SC_ID, 10);
}
#[test]
fn priority_context_roundtrip() {
for e in [Endianness::Big, Endianness::Little] {
let prio = Priority::new(12345).unwrap();
let data = encode_priority_context(prio, e).unwrap();
assert_eq!(data[0], u8::from(e == Endianness::Little));
assert_eq!(decode_priority_context(&data).unwrap(), prio);
}
}
#[test]
fn byte_exact_big_endian() {
let data = encode_priority_context(Priority::new(1337).unwrap(), Endianness::Big).unwrap();
let hex: alloc::string::String = data.iter().map(|b| alloc::format!("{b:02x}")).collect();
assert_eq!(hex, "00000539");
}
}