1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use bytes::{Buf, BufMut, Bytes, BytesMut};

use super::Metadata;

impl Metadata {
  /// Create a new [Metadata] object for the specified stream_id.
  pub fn new(index: u32) -> Metadata {
    Metadata {
      index: Some(index),
      extra: None,
    }
  }

  /// Create a new [Metadata] object for the specified stream_id.
  pub fn new_extra(index: u32, extra: Bytes) -> Metadata {
    Metadata {
      index: Some(index),
      extra: Some(extra),
    }
  }

  #[must_use]
  /// Encode the [Metadata] object into bytes for sending in a [crate::Frame].
  pub fn encode(self) -> Bytes {
    let len = 8;
    let mut bytes = BytesMut::with_capacity(len);
    bytes.fill(0);
    if let Some(index) = self.index {
      bytes.put((index).to_be_bytes().as_slice());
      bytes.put([0u8, 0, 0, 0].as_slice());

      debug_assert_eq!(bytes.len(), len, "encoded metadata is not the correct length.");

      if let Some(extra) = self.extra {
        bytes.put(extra);
      }
    }

    bytes.freeze()
  }

  /// Decode bytes into [Metadata] object
  pub fn decode(bytes: &mut Bytes) -> Result<Self, crate::Error> {
    println!("metadata bytes: {:?}", bytes.to_vec());
    if bytes.is_empty() {
      return Ok(Self {
        index: None,
        extra: None,
      });
    }

    let index = bytes.get_u32();

    let _reserved = bytes.get_u32();
    let extra = if bytes.is_empty() { None } else { Some(bytes.clone()) };
    let md = Metadata {
      index: Some(index),
      extra,
    };
    Ok(md)
  }
}