1use crate::hpack;
2
3use bytes::Bytes;
4
5use std::fmt;
6
7macro_rules! unpack_octets_4 {
20 ($buf:expr, $offset:expr, $tip:ty) => {
22 (($buf[$offset + 0] as $tip) << 24)
23 | (($buf[$offset + 1] as $tip) << 16)
24 | (($buf[$offset + 2] as $tip) << 8)
25 | (($buf[$offset + 3] as $tip) << 0)
26 };
27}
28
29#[cfg(test)]
30mod tests {
31 #[test]
32 fn test_unpack_octets_4() {
33 let buf: [u8; 4] = [0, 0, 0, 1];
34 assert_eq!(1u32, unpack_octets_4!(buf, 0, u32));
35 }
36}
37
38mod data;
39mod go_away;
40mod head;
41mod headers;
42mod ping;
43mod priority;
44mod reason;
45mod reset;
46mod settings;
47mod stream_id;
48mod util;
49mod window_update;
50
51pub use self::data::Data;
52pub use self::go_away::GoAway;
53pub use self::head::{Head, Kind};
54pub use self::headers::{
55 parse_u64, Continuation, Headers, Pseudo, PushPromise, PushPromiseHeaderError,
56};
57pub use self::ping::Ping;
58pub use self::priority::{Priority, StreamDependency};
59pub use self::reason::Reason;
60pub use self::reset::Reset;
61pub use self::settings::Settings;
62pub use self::stream_id::{StreamId, StreamIdOverflow};
63pub use self::window_update::WindowUpdate;
64
65#[cfg(feature = "unstable")]
66pub use crate::hpack::BytesStr;
67
68pub use self::settings::{
71 DEFAULT_INITIAL_WINDOW_SIZE, DEFAULT_MAX_FRAME_SIZE, DEFAULT_SETTINGS_HEADER_TABLE_SIZE,
72 MAX_MAX_FRAME_SIZE,
73};
74
75pub type FrameSize = u32;
76
77pub const HEADER_LEN: usize = 9;
78
79#[derive(Eq, PartialEq)]
80pub enum Frame<T = Bytes> {
81 Data(Data<T>),
82 Headers(Headers),
83 Priority(Priority),
84 PushPromise(PushPromise),
85 Settings(Settings),
86 Ping(Ping),
87 GoAway(GoAway),
88 WindowUpdate(WindowUpdate),
89 Reset(Reset),
90}
91
92impl<T> Frame<T> {
93 pub fn map<F, U>(self, f: F) -> Frame<U>
94 where
95 F: FnOnce(T) -> U,
96 {
97 use self::Frame::*;
98
99 match self {
100 Data(frame) => frame.map(f).into(),
101 Headers(frame) => frame.into(),
102 Priority(frame) => frame.into(),
103 PushPromise(frame) => frame.into(),
104 Settings(frame) => frame.into(),
105 Ping(frame) => frame.into(),
106 GoAway(frame) => frame.into(),
107 WindowUpdate(frame) => frame.into(),
108 Reset(frame) => frame.into(),
109 }
110 }
111}
112
113impl<T> fmt::Debug for Frame<T> {
114 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
115 use self::Frame::*;
116
117 match *self {
118 Data(ref frame) => fmt::Debug::fmt(frame, fmt),
119 Headers(ref frame) => fmt::Debug::fmt(frame, fmt),
120 Priority(ref frame) => fmt::Debug::fmt(frame, fmt),
121 PushPromise(ref frame) => fmt::Debug::fmt(frame, fmt),
122 Settings(ref frame) => fmt::Debug::fmt(frame, fmt),
123 Ping(ref frame) => fmt::Debug::fmt(frame, fmt),
124 GoAway(ref frame) => fmt::Debug::fmt(frame, fmt),
125 WindowUpdate(ref frame) => fmt::Debug::fmt(frame, fmt),
126 Reset(ref frame) => fmt::Debug::fmt(frame, fmt),
127 }
128 }
129}
130
131#[derive(Debug, Clone, PartialEq, Eq)]
133pub enum Error {
134 BadFrameSize,
136
137 TooMuchPadding,
140
141 InvalidSettingValue,
143
144 InvalidWindowUpdateValue,
146
147 InvalidPayloadLength,
150
151 InvalidPayloadAckSettings,
153
154 InvalidStreamId,
159
160 MalformedMessage,
162
163 InvalidDependencyId,
168
169 Hpack(hpack::DecoderError),
171}