wasmrs_frames/frames/
metadata.rs

1use bytes::{Buf, BufMut, Bytes, BytesMut};
2
3use crate::util::{from_u24_bytes, to_u24_bytes};
4
5use super::Metadata;
6
7impl Metadata {
8  /// Create a new [Metadata] object for the specified stream_id.
9  pub fn new(index: u32) -> Metadata {
10    Metadata {
11      index: Some(index),
12      extra: None,
13    }
14  }
15
16  /// Create a new [Metadata] object for the specified stream_id.
17  pub fn new_extra(index: u32, extra: Bytes) -> Metadata {
18    Metadata {
19      index: Some(index),
20      extra: Some(extra),
21    }
22  }
23
24  #[must_use]
25  /// Encode the [Metadata] object into bytes for sending in a [crate::Frame].
26  pub fn encode(self) -> Bytes {
27    let custom_mime_len = 4;
28    let our_len: u32 = self
29      .index
30      .map_or(0, |_| 8 + self.extra.as_ref().map(|e| e.len()).unwrap_or(0) as u32);
31
32    let mut bytes = BytesMut::with_capacity(custom_mime_len + our_len as usize);
33    bytes.fill(0);
34    bytes.put_u8(0xca);
35    bytes.put(to_u24_bytes(our_len));
36
37    if let Some(index) = &self.index {
38      bytes.put((index).to_be_bytes().as_slice());
39      bytes.put([0u8, 0, 0, 0].as_slice()); // reserved
40
41      if let Some(extra) = self.extra {
42        bytes.put(extra);
43      }
44    }
45
46    bytes.freeze()
47  }
48
49  /// Decode bytes into [Metadata] object
50  pub fn decode(bytes: &mut Bytes) -> Result<Self, crate::Error> {
51    if bytes.is_empty() {
52      return Ok(Self {
53        index: None,
54        extra: None,
55      });
56    }
57
58    if bytes[0] == 0xca {
59      // new, RSocket-aligned metadata
60
61      let _mime_type = bytes.get_u8();
62
63      let _mime_len = from_u24_bytes(&bytes.split_to(3)) as usize;
64
65      let index = bytes.get_u32();
66      let _reserved = bytes.get_u32();
67
68      let extra = if bytes.is_empty() {
69        None
70      } else {
71        Some(bytes.split_to(bytes.remaining()))
72      };
73
74      Ok(Self {
75        index: Some(index),
76        extra,
77      })
78    } else {
79      let index = bytes.get_u32();
80
81      let _reserved = bytes.get_u32();
82      let extra = if bytes.is_empty() { None } else { Some(bytes.clone()) };
83      let md = Metadata {
84        index: Some(index),
85        extra,
86      };
87      Ok(md)
88    }
89  }
90}
91
92#[cfg(test)]
93mod test {
94  use super::*;
95  use anyhow::Result;
96
97  #[test]
98  fn test_rt() -> Result<()> {
99    let md = Metadata::new(32);
100    let bytes = md.clone().encode();
101    let mut bytes = bytes.clone();
102    let md2 = Metadata::decode(&mut bytes)?;
103
104    assert_eq!(md, md2);
105
106    Ok(())
107  }
108
109  #[test]
110  fn test_old() -> Result<()> {
111    let md = Metadata::new(48);
112
113    let mut bytes: Bytes = vec![0, 0, 0, 0x30, 0, 0, 0, 0].into();
114    let md2 = Metadata::decode(&mut bytes)?;
115
116    assert_eq!(md, md2);
117
118    Ok(())
119  }
120
121  #[test]
122  fn test_new() -> Result<()> {
123    let md = Metadata::new(48);
124    let mut bytes: Bytes = vec![0xca, 0, 0, 8, 0, 0, 0, 0x30, 0, 0, 0, 0].into();
125    let md2 = Metadata::decode(&mut bytes)?;
126
127    assert_eq!(md, md2);
128
129    Ok(())
130  }
131
132  #[test]
133  fn test_new_extra() -> Result<()> {
134    let md = Metadata::new_extra(48, b"hello".to_vec().into());
135    let mut bytes = md.clone().encode();
136
137    let md2 = Metadata::decode(&mut bytes)?;
138
139    assert_eq!(md, md2);
140
141    Ok(())
142  }
143}