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 HeaderListWayTooLarge,
165
166 InvalidDependencyId,
171
172 Hpack(hpack::DecoderError),
174}