Skip to main content

webui_protocol/plugin/
fast.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT license.
3
4use crate::{ProtocolError, Result};
5
6const FAST_ELEMENT_DATA_LEN: usize = 4;
7
8/// FAST hydration element metadata encoded in plugin fragments.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub struct FastElementData {
11    /// Number of dynamic attribute bindings on the element.
12    pub binding_count: u32,
13}
14
15impl FastElementData {
16    /// Encode this metadata using the FAST 4-byte little-endian wire format.
17    #[must_use]
18    pub fn encode(self) -> [u8; FAST_ELEMENT_DATA_LEN] {
19        self.binding_count.to_le_bytes()
20    }
21
22    /// Decode FAST hydration metadata from protocol bytes.
23    ///
24    /// # Errors
25    ///
26    /// Returns [`ProtocolError::Validation`] when the payload length is not 4 bytes.
27    pub fn decode(bytes: &[u8]) -> Result<Self> {
28        if bytes.len() != FAST_ELEMENT_DATA_LEN {
29            return Err(ProtocolError::Validation(format!(
30                "FAST element data must be {FAST_ELEMENT_DATA_LEN} bytes, received {}",
31                bytes.len()
32            )));
33        }
34
35        Ok(Self {
36            binding_count: u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]),
37        })
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use super::FastElementData;
44    use crate::ProtocolError;
45
46    #[test]
47    fn test_fast_element_data_roundtrip() {
48        let encoded = FastElementData { binding_count: 3 }.encode();
49        let decoded = FastElementData::decode(&encoded).expect("decode should succeed");
50        assert_eq!(decoded.binding_count, 3);
51    }
52
53    #[test]
54    fn test_fast_element_data_rejects_invalid_length() {
55        let result = FastElementData::decode(&[1, 2]);
56        assert!(
57            matches!(result, Err(ProtocolError::Validation(ref msg)) if msg.contains("4 bytes")),
58            "invalid payload length should be rejected: {result:?}"
59        );
60    }
61}