use crate::protocol::dds::api::dds_type::DdsType;
use crate::protocol::dds::api::error::DdsApiError;
use crate::protocol::dds::byte_cursor::{ByteCursor, ByteWriter};
use super::{make_cursor, make_writer};
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Uuid {
pub uuid: [u8; 16],
}
impl Uuid {
pub fn nil() -> Self {
Self { uuid: [0u8; 16] }
}
pub fn from_bytes(bytes: [u8; 16]) -> Self {
Self { uuid: bytes }
}
pub(crate) fn serialize_inner(&self, w: &mut ByteWriter<'_>) -> Result<(), DdsApiError> {
w.write_bytes(&self.uuid)?;
Ok(())
}
pub(crate) fn deserialize_inner(r: &mut ByteCursor<'_>) -> Result<Self, DdsApiError> {
let raw = r.read_bytes(16)?;
let mut uuid = [0u8; 16];
uuid.copy_from_slice(raw);
Ok(Self { uuid })
}
}
impl DdsType for Uuid {
const TYPE_NAME: &'static str = "unique_identifier_msgs::msg::dds_::UUID_";
fn serialize(&self, buf: &mut [u8]) -> Result<usize, DdsApiError> {
let mut w = make_writer(buf)?;
self.serialize_inner(&mut w)?;
Ok(4 + w.position())
}
fn deserialize(payload: &[u8]) -> Result<Self, DdsApiError> {
let mut r = make_cursor(payload)?;
Self::deserialize_inner(&mut r)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn uuid_type_name() {
assert_eq!(Uuid::TYPE_NAME, "unique_identifier_msgs::msg::dds_::UUID_");
}
#[test]
fn uuid_round_trip() {
let original = Uuid::from_bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
let mut buf = [0u8; 64];
let written = original.serialize(&mut buf).unwrap();
let decoded = Uuid::deserialize(&buf[..written]).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn uuid_wire_size() {
let u = Uuid::nil();
let mut buf = [0u8; 64];
let written = u.serialize(&mut buf).unwrap();
assert_eq!(written, 20);
assert_eq!(&buf[0..4], &[0x00, 0x01, 0x00, 0x00]);
assert_eq!(&buf[4..20], &[0u8; 16]);
}
#[test]
fn uuid_byte_layout_not_a_sequence() {
let u = Uuid::from_bytes([0xFF; 16]);
let mut buf = [0u8; 64];
let written = u.serialize(&mut buf).unwrap();
assert_eq!(buf[4], 0xFF);
assert_eq!(written, 20);
}
#[test]
fn uuid_nil() {
assert_eq!(Uuid::nil().uuid, [0u8; 16]);
}
#[test]
fn uuid_from_bytes() {
let bytes = [42u8; 16];
let u = Uuid::from_bytes(bytes);
assert_eq!(u.uuid, bytes);
}
}