miku_h2/frame/
priority.rs1use bytes::BufMut;
2
3use crate::frame::*;
4
5#[derive(Debug, Copy, Clone, Eq, PartialEq)]
6pub struct Priority {
11 stream_id: StreamId,
13
14 dependency: StreamDependency,
16}
17
18#[derive(Debug, Copy, Clone, Eq, PartialEq)]
19pub struct StreamDependency {
20 dependency_id: StreamId,
22
23 weight: u8,
27
28 is_exclusive: bool,
30}
31
32impl Priority {
35 pub fn new(stream_id: StreamId, dependency: StreamDependency) -> Self {
37 assert!(stream_id != 0);
38 Priority {
39 stream_id,
40 dependency,
41 }
42 }
43
44 pub fn load(head: Head, payload: &[u8]) -> Result<Self, Error> {
46 let dependency = StreamDependency::load(payload)?;
47
48 if dependency.dependency_id() == head.stream_id() {
49 return Err(Error::InvalidDependencyId);
50 }
51
52 Ok(Priority {
53 stream_id: head.stream_id(),
54 dependency,
55 })
56 }
57
58 pub fn head(&self) -> Head {
59 Head::new(Kind::Priority, 0, self.stream_id)
60 }
61
62 pub fn stream_id(&self) -> StreamId {
63 self.stream_id
64 }
65
66 pub fn encode<B: BufMut>(&self, dst: &mut B) {
67 let head = self.head();
68 head.encode(5, dst);
69
70 self.dependency.encode(dst);
78 }
79}
80
81impl<B> From<Priority> for Frame<B> {
82 fn from(src: Priority) -> Self {
83 Frame::Priority(src)
84 }
85}
86
87impl StreamDependency {
90 pub fn new(dependency_id: StreamId, weight: u8, is_exclusive: bool) -> Self {
92 StreamDependency {
93 dependency_id,
94 weight,
95 is_exclusive,
96 }
97 }
98
99 pub fn load(src: &[u8]) -> Result<Self, Error> {
101 if src.len() != 5 {
102 return Err(Error::InvalidPayloadLength);
103 }
104
105 let (dependency_id, is_exclusive) = StreamId::parse(&src[..4]);
107
108 let weight = src[4];
110
111 Ok(StreamDependency::new(dependency_id, weight, is_exclusive))
112 }
113
114 pub fn dependency_id(&self) -> StreamId {
115 self.dependency_id
116 }
117
118 pub fn weight(&self) -> u8 {
119 self.weight
120 }
121
122 pub fn is_exclusive(&self) -> bool {
123 self.is_exclusive
124 }
125
126 pub fn encode<T: BufMut>(&self, dst: &mut T) {
127 let dependency_id: u32 = self.dependency_id().into();
128
129 let mut buf = dependency_id.to_be_bytes();
130
131 if self.is_exclusive {
132 buf[0] |= 0x80;
133 }
134
135 dst.put_slice(&buf);
136 dst.put_u8(self.weight);
137 }
138}
139
140mod tests {
141
142 #[test]
143 fn test_priority_frame() {
144 use crate::frame::{self, Priority, StreamDependency, StreamId};
145
146 let mut dependency_buf = Vec::new();
147 let dependency = StreamDependency::new(StreamId::zero(), 201, false);
148 dependency.encode(&mut dependency_buf);
149 let dependency = StreamDependency::load(&dependency_buf).unwrap();
150 assert_eq!(dependency.dependency_id(), StreamId::zero());
151 assert_eq!(dependency.weight(), 201);
152 assert!(!dependency.is_exclusive());
153
154 let priority = Priority::new(StreamId::from(3), dependency);
155 let mut priority_buf = Vec::new();
156 priority.encode(&mut priority_buf);
157 let priority = Priority::load(priority.head(), &priority_buf[frame::HEADER_LEN..]).unwrap();
158 assert_eq!(priority.stream_id(), StreamId::from(3));
159 assert_eq!(priority.dependency.dependency_id(), StreamId::zero());
160 assert_eq!(priority.dependency.weight(), 201);
161 assert!(!priority.dependency.is_exclusive());
162 }
163}