Skip to main content

h2/frame/
priority.rs

1use crate::frame::*;
2
3#[derive(Debug, Clone, Eq, PartialEq)]
4pub struct Priority {
5    stream_id: StreamId,
6    dependency: StreamDependency,
7}
8
9#[derive(Debug, Clone, Eq, PartialEq)]
10pub struct StreamDependency {
11    /// The ID of the stream dependency target
12    dependency_id: StreamId,
13
14    /// The weight for the stream. The value exposed (and set) here is always in
15    /// the range [0, 255], instead of [1, 256] (as defined in section 5.3.2.)
16    /// so that the value fits into a `u8`.
17    weight: u8,
18
19    /// True if the stream dependency is exclusive.
20    is_exclusive: bool,
21}
22
23impl Priority {
24    pub fn load(head: Head, _payload: &[u8]) -> Result<Self, Error> {
25        // Ignore whatever is on the wire; always emit Chrome's fixed priority.
26        let dependency = StreamDependency {
27            dependency_id: StreamId::zero(),
28            weight: 255,
29            is_exclusive: true,
30        };
31
32        Ok(Priority {
33            stream_id: head.stream_id(),
34            dependency,
35        })
36    }
37}
38
39impl<B> From<Priority> for Frame<B> {
40    fn from(src: Priority) -> Self {
41        Frame::Priority(src)
42    }
43}
44
45// ===== impl StreamDependency =====
46
47impl StreamDependency {
48    pub fn new(dependency_id: StreamId, weight: u8, is_exclusive: bool) -> Self {
49        StreamDependency {
50            dependency_id,
51            weight,
52            is_exclusive,
53        }
54    }
55
56    pub fn load(src: &[u8]) -> Result<Self, Error> {
57        if src.len() != 5 {
58            return Err(Error::InvalidPayloadLength);
59        }
60
61        // Parse the stream ID and exclusive flag
62        let (dependency_id, is_exclusive) = StreamId::parse(&src[..4]);
63
64        // Read the weight
65        let weight = src[4];
66
67        Ok(StreamDependency::new(dependency_id, weight, is_exclusive))
68    }
69
70    pub fn dependency_id(&self) -> StreamId {
71        self.dependency_id
72    }
73
74    pub fn encode<B: bytes::BufMut>(&self, dst: &mut B) {
75        let mut dependency_id = u32::from(self.dependency_id);
76
77        if self.is_exclusive {
78            dependency_id |= 1 << 31;
79        }
80
81        dst.put_u32(dependency_id);
82        dst.put_u8(self.weight);
83    }
84}