@@ -21,11 +21,21 @@ static INDENT_STR: &str =
2121pub struct ClarifySliceWriter < ' a > {
2222 writer : SliceWriter < ' a > ,
2323
24+ clarifier : Clarifier ,
25+ }
26+
27+ /// Clarifier that creates HEX with comments
28+ pub struct Clarifier {
2429 // Buffer into which debug HEX and comments are written
2530 debug_ref : Rc < RefCell < Vec < u8 > > > ,
2631
32+ // Position in the buffer is used to track how long is the current sub-message
33+ last_position : u32 ,
34+
2735 /// Used for debug indentation
28- depth : Vec < u32 > ,
36+ ///
37+ /// Pushes writer positions on the stack
38+ depth : Vec < Option < u32 > > ,
2939
3040 indent_enabled : bool ,
3141 comment_writer : Box < dyn CommentWriter > ,
@@ -37,13 +47,14 @@ pub struct FinishOutputs<'a> {
3747 //pub debug_ref: Vec<u8>,
3848}
3949
40- impl < ' a > ClarifySliceWriter < ' a > {
41- /// Create a new encoder with the given byte slice as a backing buffer.
42- pub fn new ( bytes : & ' a mut [ u8 ] , debug_ref : Rc < RefCell < Vec < u8 > > > , comment_xml : bool ) -> Self {
50+ impl Clarifier {
51+ pub fn new ( debug_ref : Rc < RefCell < Vec < u8 > > > , comment_xml : bool ) -> Self {
4352 Self {
44- writer : SliceWriter :: new ( bytes) ,
4553 debug_ref,
54+
55+ last_position : 0 ,
4656 depth : Vec :: new ( ) ,
57+
4758 indent_enabled : true ,
4859 comment_writer : if comment_xml {
4960 Box :: new ( XmlCommentWriter :: default ( ) )
@@ -52,6 +63,16 @@ impl<'a> ClarifySliceWriter<'a> {
5263 } ,
5364 }
5465 }
66+ }
67+
68+ impl < ' a > ClarifySliceWriter < ' a > {
69+ /// Create a new encoder with the given byte slice as a backing buffer.
70+ pub fn new ( bytes : & ' a mut [ u8 ] , debug_ref : Rc < RefCell < Vec < u8 > > > , comment_xml : bool ) -> Self {
71+ Self {
72+ writer : SliceWriter :: new ( bytes) ,
73+ clarifier : Clarifier :: new ( debug_ref, comment_xml) ,
74+ }
75+ }
5576
5677 // /// Encode a value which impls the [`Encode`] trait.
5778 // pub fn encode<T: Encode>(&mut self, encodable: &T) -> Result<()> {
@@ -118,13 +139,28 @@ impl<'a> ClarifySliceWriter<'a> {
118139 // self.error(ErrorKind::Length { tag: Tag::Sequence })
119140 // }
120141 // }
142+
143+ /// Reserve a portion of the internal buffer, updating the internal cursor
144+ /// position and returning a mutable slice.
145+ fn reserve ( & mut self , len : impl TryInto < Length > ) -> Result < & mut [ u8 ] > {
146+ self . writer . reserve ( len)
147+ }
148+ }
149+
150+ impl Clarifier {
121151 /// Returns indentation, for example "\n\t" for depth == 1
122152 pub fn indent_str ( & self ) -> & ' static str {
123153 let ilen = self . depth . len ( ) * 1 ;
124154 let ilen = ilen. min ( INDENT_STR . len ( ) ) ;
125155 & INDENT_STR [ ..ilen]
126156 }
127157
158+ pub fn write_clarify_indent_if_enabled ( & mut self ) {
159+ if self . indent_enabled {
160+ self . write_clarify_indent ( ) ;
161+ }
162+ }
163+
128164 /// Writes indentation to debug output, for example "\n\t" for depth == 1
129165 pub fn write_clarify_indent ( & mut self ) {
130166 let indent = self . indent_str ( ) ;
@@ -180,54 +216,36 @@ impl<'a> ClarifySliceWriter<'a> {
180216 }
181217 }
182218
183- /// Reserve a portion of the internal buffer, updating the internal cursor
184- /// position and returning a mutable slice.
185- fn reserve ( & mut self , len : impl TryInto < Length > ) -> Result < & mut [ u8 ] > {
186- self . writer . reserve ( len)
187- }
188-
189- fn clarify_start_value_type_str ( & mut self , type_name : & str ) {
219+ /// input: u32::from(self.writer.position())
220+ pub fn clarify_start_value_type_str ( & mut self , writer_pos : Option < u32 > , type_name : & str ) {
190221 self . indent_enabled = true ;
191- self . depth . push ( u32 :: from ( self . writer . position ( ) ) ) ;
222+ self . depth . push ( writer_pos ) ;
192223
193224 let type_name = strip_transparent_types ( type_name) ;
194225 self . write_clarify_type_str ( "type" , & type_name) ;
195226 }
196227
197- fn clarify_end_value_type_str ( & mut self , type_name : & str ) {
198- let current = u32:: from ( self . writer . position ( ) ) ;
199- let last_pos = self . depth . pop ( ) . unwrap_or ( current) ;
200- let diff = current - last_pos;
201-
202- if diff > 16 {
203- let type_name = strip_transparent_types ( type_name) ;
204- self . write_clarify_indent ( ) ;
205- self . write_clarify_type_str ( "end" , type_name. as_ref ( ) ) ;
206- }
207- }
208- }
209-
210- impl < ' a > Writer for ClarifySliceWriter < ' a > {
211- fn write ( & mut self , slice : & [ u8 ] ) -> Result < ( ) > {
212- self . reserve ( slice. len ( ) ) ?. copy_from_slice ( slice) ;
213-
214- if self . indent_enabled {
215- self . write_clarify_indent ( ) ;
228+ fn clarify_end_value_type_str ( & mut self , writer_pos : Option < u32 > , type_name : & str ) {
229+ let last_pos = self . depth . pop ( ) . unwrap_or ( writer_pos) ;
230+
231+ match ( writer_pos, last_pos) {
232+ ( Some ( writer_pos) , Some ( last_pos) ) => {
233+ let diff = writer_pos - last_pos;
234+ if diff < 16 {
235+ // ignore short runs
236+ return ;
237+ }
238+ }
239+ _ => { }
216240 }
217241
218- self . write_clarify_hex ( slice) ;
219- Ok ( ( ) )
220- }
221-
222- fn clarify_start_value_type < T > ( & mut self ) {
223- self . clarify_start_value_type_str ( & tynm:: type_name :: < T > ( ) ) ;
224- }
225- fn clarify_end_value_type < T > ( & mut self ) {
226- self . clarify_end_value_type_str ( & tynm:: type_name :: < T > ( ) ) ;
242+ let type_name = strip_transparent_types ( type_name) ;
243+ self . write_clarify_indent ( ) ;
244+ self . write_clarify_type_str ( "end" , type_name. as_ref ( ) ) ;
227245 }
228246
229247 /// for better tag-length pretty-printing inline
230- fn clarify_end_tag ( & mut self , _tag : & Tag ) {
248+ pub fn clarify_end_tag ( & mut self , _tag : & Tag ) {
231249 // just to print a single length byte without indent
232250 self . indent_enabled = false ;
233251 }
@@ -240,11 +258,18 @@ impl<'a> Writer for ClarifySliceWriter<'a> {
240258 // self.indent_enabled = enabled;
241259 // }
242260
243- fn clarify_field_name ( & mut self , field_name : & str ) {
261+ pub fn clarify_field_name ( & mut self , field_name : & str ) {
244262 self . write_clarify_indent ( ) ;
245263 self . write_clarify_type_str ( "field" , field_name) ;
246264 }
247265
266+ pub fn clarify_start_value_type < T > ( & mut self ) {
267+ self . clarify_start_value_type_str ( Some ( self . last_position ) , & tynm:: type_name :: < T > ( ) ) ;
268+ }
269+ pub fn clarify_end_value_type < T > ( & mut self ) {
270+ self . clarify_end_value_type_str ( Some ( self . last_position ) , & tynm:: type_name :: < T > ( ) ) ;
271+ }
272+
248273 // fn clarify_end_length(&mut self, tag: Option<&Tag>, length: Length) {
249274 // self.indent_enabled = true;
250275 // if let Some(tag) = tag {
@@ -264,15 +289,23 @@ impl<'a> Writer for ClarifySliceWriter<'a> {
264289 // self.write_debug_int(value);
265290 // }
266291
267- fn clarify_choice ( & mut self , choice_name : & [ u8 ] ) {
292+ pub fn clarify_choice ( & mut self , choice_name : & [ u8 ] ) {
268293 self . write_clarify_indent ( ) ;
269294 if let Ok ( choice_name) = std:: str:: from_utf8 ( choice_name) {
270295 self . write_clarify_type_str ( "CHOICE" , choice_name) ;
271296 }
272297 }
298+ }
299+
300+ impl < ' a > Writer for ClarifySliceWriter < ' a > {
301+ fn write ( & mut self , slice : & [ u8 ] ) -> Result < ( ) > {
302+ self . reserve ( slice. len ( ) ) ?. copy_from_slice ( slice) ;
303+ self . clarifier . last_position += slice. len ( ) as u32 ;
273304
274- fn is_clarify ( & self ) -> bool {
275- true
305+ self . clarifier . write_clarify_indent_if_enabled ( ) ;
306+ self . clarifier . write_clarify_hex ( slice) ;
307+
308+ Ok ( ( ) )
276309 }
277310}
278311
0 commit comments