1use thiserror::Error;
8
9pub const VTX_PREFIX: [u8; 3] = [0x56, 0x54, 0x58]; pub const VTX_VERSION_V1: u8 = 0x01;
11pub const VTX_MAGIC_V1: [u8; 4] = [VTX_PREFIX[0], VTX_PREFIX[1], VTX_PREFIX[2], VTX_VERSION_V1];
12
13#[derive(Debug, Error)]
14pub enum VtxFormatError {
15 #[error("vtx file too short")]
16 TooShort,
17
18 #[error("invalid vtx prefix (expected 'VTX')")]
19 InvalidPrefix,
20
21 #[error("unsupported vtx version: {0}")]
22 UnsupportedVersion(u8),
23}
24
25pub fn encode_v1(component_bytes: &[u8]) -> Vec<u8> {
27 let mut out = Vec::with_capacity(VTX_MAGIC_V1.len() + component_bytes.len());
28 out.extend_from_slice(&VTX_MAGIC_V1);
29 out.extend_from_slice(component_bytes);
30 out
31}
32
33pub fn decode(bytes: &[u8]) -> Result<(u8, &[u8]), VtxFormatError> {
35 if bytes.len() < 4 {
36 return Err(VtxFormatError::TooShort);
37 }
38 if bytes[0..3] != VTX_PREFIX {
39 return Err(VtxFormatError::InvalidPrefix);
40 }
41
42 let version = bytes[3];
43 match version {
44 VTX_VERSION_V1 => Ok((version, &bytes[4..])),
45 other => Err(VtxFormatError::UnsupportedVersion(other)),
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn test_encode_v1_structure() {
55 let payload = b"wasm-magic";
56 let encoded = encode_v1(payload);
57
58 assert_eq!(&encoded[0..4], &VTX_MAGIC_V1);
60 assert_eq!(&encoded[4..], payload);
62 }
63
64 #[test]
65 fn test_decode_valid_v1() {
66 let payload = b"component-data";
67 let mut data = Vec::new();
68 data.extend_from_slice(&VTX_MAGIC_V1);
69 data.extend_from_slice(payload);
70
71 let result = decode(&data);
72 assert!(result.is_ok());
73 let (version, body) = result.unwrap();
74
75 assert_eq!(version, VTX_VERSION_V1);
76 assert_eq!(body, payload);
77 }
78
79 #[test]
80 fn test_decode_too_short() {
81 let data = b"VTX"; let result = decode(data);
83 assert!(matches!(result, Err(VtxFormatError::TooShort)));
84 }
85
86 #[test]
87 fn test_decode_invalid_prefix() {
88 let data = b"VTY\x01payload";
90 let result = decode(data);
91 assert!(matches!(result, Err(VtxFormatError::InvalidPrefix)));
92 }
93
94 #[test]
95 fn test_decode_unsupported_version() {
96 let data = b"VTX\x02payload";
98 let result = decode(data);
99
100 if let Err(VtxFormatError::UnsupportedVersion(v)) = result {
101 assert_eq!(v, 2);
102 } else {
103 panic!("Should return UnsupportedVersion error");
104 }
105 }
106}