Add DebugFlags helper, improve format of HEADERS and SETTINGS frames
This commit is contained in:
		| @@ -225,16 +225,9 @@ impl From<DataFlags> for u8 { | ||||
|  | ||||
| impl fmt::Debug for DataFlags { | ||||
|     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||
|         let mut f = fmt.debug_struct("DataFlags"); | ||||
|  | ||||
|         if self.is_end_stream() { | ||||
|             f.field("end_stream", &true); | ||||
|         } | ||||
|  | ||||
|         if self.is_padded() { | ||||
|             f.field("padded", &true); | ||||
|         } | ||||
|  | ||||
|         f.finish() | ||||
|         util::debug_flags(fmt, self.0) | ||||
|             .flag_if(self.is_end_stream(), "END_STREAM") | ||||
|             .flag_if(self.is_padded(), "PADDED") | ||||
|             .finish() | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| use super::{StreamDependency, StreamId}; | ||||
| use super::{util, StreamDependency, StreamId}; | ||||
| use frame::{Error, Frame, Head, Kind}; | ||||
| use hpack; | ||||
|  | ||||
| @@ -274,12 +274,17 @@ impl<T> From<Headers> for Frame<T> { | ||||
|  | ||||
| impl fmt::Debug for Headers { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|         f.debug_struct("Headers") | ||||
|         let mut builder = f.debug_struct("Headers"); | ||||
|         builder | ||||
|             .field("stream_id", &self.stream_id) | ||||
|             .field("stream_dep", &self.stream_dep) | ||||
|             .field("flags", &self.flags) | ||||
|             // `fields` and `pseudo` purposefully not included | ||||
|             .finish() | ||||
|             .field("flags", &self.flags); | ||||
|  | ||||
|         if let Some(ref dep) = self.stream_dep { | ||||
|             builder.field("stream_dep", dep); | ||||
|         } | ||||
|  | ||||
|         // `fields` and `pseudo` purposefully not included | ||||
|         builder.finish() | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -656,11 +661,11 @@ impl From<HeadersFlag> for u8 { | ||||
|  | ||||
| impl fmt::Debug for HeadersFlag { | ||||
|     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||
|         fmt.debug_struct("HeadersFlag") | ||||
|             .field("end_stream", &self.is_end_stream()) | ||||
|             .field("end_headers", &self.is_end_headers()) | ||||
|             .field("padded", &self.is_padded()) | ||||
|             .field("priority", &self.is_priority()) | ||||
|         util::debug_flags(fmt, self.0) | ||||
|             .flag_if(self.is_end_headers(), "END_HEADERS") | ||||
|             .flag_if(self.is_end_stream(), "END_STREAM") | ||||
|             .flag_if(self.is_padded(), "PADDED") | ||||
|             .flag_if(self.is_priority(), "PRIORITY") | ||||
|             .finish() | ||||
|     } | ||||
| } | ||||
| @@ -704,9 +709,9 @@ impl From<PushPromiseFlag> for u8 { | ||||
|  | ||||
| impl fmt::Debug for PushPromiseFlag { | ||||
|     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||
|         fmt.debug_struct("PushPromiseFlag") | ||||
|             .field("end_headers", &self.is_end_headers()) | ||||
|             .field("padded", &self.is_padded()) | ||||
|         util::debug_flags(fmt, self.0) | ||||
|             .flag_if(self.is_end_headers(), "END_HEADERS") | ||||
|             .flag_if(self.is_padded(), "PADDED") | ||||
|             .finish() | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,9 @@ | ||||
| use bytes::{BufMut, BytesMut}; | ||||
| use frame::{Error, Frame, FrameSize, Head, Kind, StreamId}; | ||||
| use std::fmt; | ||||
|  | ||||
| #[derive(Debug, Clone, Default, Eq, PartialEq)] | ||||
| use bytes::{BufMut, BytesMut}; | ||||
| use frame::{util, Error, Frame, FrameSize, Head, Kind, StreamId}; | ||||
|  | ||||
| #[derive(Clone, Default, Eq, PartialEq)] | ||||
| pub struct Settings { | ||||
|     flags: SettingsFlags, | ||||
|     // Fields | ||||
| @@ -27,7 +29,7 @@ pub enum Setting { | ||||
|     MaxHeaderListSize(u32), | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Copy, Clone, Eq, PartialEq, Default)] | ||||
| #[derive(Copy, Clone, Eq, PartialEq, Default)] | ||||
| pub struct SettingsFlags(u8); | ||||
|  | ||||
| const ACK: u8 = 0x1; | ||||
| @@ -231,6 +233,36 @@ impl<T> From<Settings> for Frame<T> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl fmt::Debug for Settings { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|         let mut builder = f.debug_struct("Settings"); | ||||
|         builder.field("flags", &self.flags); | ||||
|  | ||||
|         self.for_each(|setting| match setting { | ||||
|             Setting::EnablePush(v) => { | ||||
|                 builder.field("enable_push", &v); | ||||
|             } | ||||
|             Setting::HeaderTableSize(v) => { | ||||
|                 builder.field("header_table_size", &v); | ||||
|             } | ||||
|             Setting::InitialWindowSize(v) => { | ||||
|                 builder.field("initial_window_size", &v); | ||||
|             } | ||||
|             Setting::MaxConcurrentStreams(v) => { | ||||
|                 builder.field("max_concurrent_streams", &v); | ||||
|             } | ||||
|             Setting::MaxFrameSize(v) => { | ||||
|                 builder.field("max_frame_size", &v); | ||||
|             } | ||||
|             Setting::MaxHeaderListSize(v) => { | ||||
|                 builder.field("max_header_list_size", &v); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         builder.finish() | ||||
|     } | ||||
| } | ||||
|  | ||||
| // ===== impl Setting ===== | ||||
|  | ||||
| impl Setting { | ||||
| @@ -310,3 +342,11 @@ impl From<SettingsFlags> for u8 { | ||||
|         src.0 | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl fmt::Debug for SettingsFlags { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|         util::debug_flags(f, self.0) | ||||
|             .flag_if(self.is_ack(), "ACK") | ||||
|             .finish() | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| use std::fmt; | ||||
|  | ||||
| use super::Error; | ||||
| use bytes::Bytes; | ||||
|  | ||||
| @@ -35,3 +37,42 @@ pub fn strip_padding(payload: &mut Bytes) -> Result<u8, Error> { | ||||
|  | ||||
|     Ok(pad_len as u8) | ||||
| } | ||||
|  | ||||
| pub(super) fn debug_flags<'a, 'f>(fmt: &'a mut fmt::Formatter<'f>, bits: u8) -> DebugFlags<'a, 'f> { | ||||
|     let result = write!(fmt, "({:#x}", bits); | ||||
|     DebugFlags { | ||||
|         fmt, | ||||
|         result, | ||||
|         started: false, | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub(super) struct DebugFlags<'a, 'f> { | ||||
|     fmt: &'a mut fmt::Formatter<'f>, | ||||
|     result: fmt::Result, | ||||
|     started: bool, | ||||
| } | ||||
|  | ||||
| impl<'a, 'f> DebugFlags<'a, 'f> { | ||||
|     pub(super) fn flag_if(&mut self, enabled: bool, name: &str) -> &mut Self { | ||||
|         if enabled { | ||||
|             self.result = self.result.and_then(|()| { | ||||
|                 let prefix = if self.started { | ||||
|                     " | " | ||||
|                 } else { | ||||
|                     self.started = true; | ||||
|                     ": " | ||||
|                 }; | ||||
|  | ||||
|                 write!(self.fmt, "{}{}", prefix, name) | ||||
|             }); | ||||
|         } | ||||
|         self | ||||
|     } | ||||
|  | ||||
|     pub(super) fn finish(&mut self) -> fmt::Result { | ||||
|         self.result.and_then(|()| { | ||||
|             write!(self.fmt, ")") | ||||
|         }) | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user