vtx_format/
decode.rs

1use crate::{
2    DecodeWithMetadataResult, DecodedVtx, VtxFormatError, VTX_PREFIX, VTX_VERSION_V1,
3    VTX_VERSION_V2,
4};
5
6/// 解码:返回 (version, component_bytes_slice),对 v2 会跳过 metadata。
7pub fn decode(bytes: &[u8]) -> Result<(u8, &[u8]), VtxFormatError> {
8    let decoded = decode_with_metadata(bytes)?;
9    Ok((decoded.version, decoded.component))
10}
11
12/// 解码并返回 metadata(仅 v2);v1 的 metadata 为 None。
13pub fn decode_with_metadata(bytes: &[u8]) -> DecodeWithMetadataResult<'_> {
14    if bytes.len() < 4 {
15        return Err(VtxFormatError::TooShort);
16    }
17    if bytes[0..3] != VTX_PREFIX {
18        return Err(VtxFormatError::InvalidPrefix);
19    }
20
21    let version = bytes[3];
22    match version {
23        VTX_VERSION_V1 => Ok(DecodedVtx {
24            version,
25            metadata: None,
26            component: &bytes[4..],
27        }),
28        VTX_VERSION_V2 => {
29            let (meta, component) = decode_v2_parts(bytes)?;
30            Ok(DecodedVtx {
31                version,
32                metadata: Some(meta),
33                component,
34            })
35        }
36        other => Err(VtxFormatError::UnsupportedVersion(other)),
37    }
38}
39
40fn decode_v2_parts(bytes: &[u8]) -> Result<(&[u8], &[u8]), VtxFormatError> {
41    if bytes.len() < 8 {
42        return Err(VtxFormatError::TooShort);
43    }
44    let meta_len = u32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]) as usize;
45    let meta_start = 8usize;
46    let meta_end = meta_start.saturating_add(meta_len);
47    if meta_end > bytes.len() {
48        return Err(VtxFormatError::InvalidMetadataLength);
49    }
50    Ok((&bytes[meta_start..meta_end], &bytes[meta_end..]))
51}