Skip to main content

voidmc_codec/primitives/
uuid.rs

1use crate::{Decode, DecodeError, Encode};
2use uuid::Uuid;
3
4impl Encode for Uuid {
5    fn encode(&self, buf: &mut Vec<u8>) {
6        buf.extend_from_slice(self.as_bytes());
7    }
8}
9
10impl Decode for Uuid {
11    fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
12        if buf.len() < 16 {
13            return Err(DecodeError::UnexpectedEof);
14        }
15
16        let uuid_bytes = &buf[..16];
17        *buf = &buf[16..];
18
19        Ok(Uuid::from_bytes(uuid_bytes.try_into().unwrap()))
20    }
21}
22
23#[cfg(test)]
24mod tests {
25    use super::*;
26
27    #[test]
28    fn test_uuid_encode_decode() {
29        let uuid = Uuid::new_v4();
30        let mut buf = Vec::new();
31        uuid.encode(&mut buf);
32
33        assert_eq!(buf.len(), 16, "UUID should encode to 16 bytes");
34
35        let mut slice = buf.as_slice();
36        let decoded = Uuid::decode(&mut slice).unwrap();
37
38        assert_eq!(decoded, uuid);
39        assert_eq!(slice.len(), 0, "All bytes should be consumed");
40    }
41
42    #[test]
43    fn test_uuid_exact_bytes() {
44        let uuid = Uuid::nil();
45        let mut buf = Vec::new();
46        uuid.encode(&mut buf);
47
48        assert_eq!(
49            buf,
50            vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
51            "Nil UUID should encode as all zeros"
52        );
53    }
54
55    #[test]
56    fn test_uuid_truncated() {
57        let mut slice = &[0u8; 15][..];
58        let result = Uuid::decode(&mut slice);
59
60        assert_eq!(result, Err(DecodeError::UnexpectedEof));
61    }
62
63    #[test]
64    fn test_uuid_known_value() {
65        let uuid_str = "f47ac10b-58cc-4372-a567-0e02b2c3d479";
66        let uuid = uuid_str.parse::<Uuid>().unwrap();
67
68        let mut buf = Vec::new();
69        uuid.encode(&mut buf);
70
71        let mut slice = buf.as_slice();
72        let decoded = Uuid::decode(&mut slice).unwrap();
73
74        assert_eq!(decoded.to_string(), uuid_str);
75    }
76
77    #[test]
78    fn test_uuid_roundtrip_multiple() {
79        for _ in 0..100 {
80            let uuid = Uuid::new_v4();
81            let mut buf = Vec::new();
82            uuid.encode(&mut buf);
83
84            let mut slice = buf.as_slice();
85            let decoded = Uuid::decode(&mut slice).unwrap();
86
87            assert_eq!(decoded, uuid);
88        }
89    }
90}