@@ -21,11 +21,21 @@ static INDENT_STR: &str =
21
21
pub struct ClarifySliceWriter < ' a > {
22
22
writer : SliceWriter < ' a > ,
23
23
24
+ clarifier : Clarifier ,
25
+ }
26
+
27
+ /// Clarifier that creates HEX with comments
28
+ pub struct Clarifier {
24
29
// Buffer into which debug HEX and comments are written
25
30
debug_ref : Rc < RefCell < Vec < u8 > > > ,
26
31
32
+ // Position in the buffer is used to track how long is the current sub-message
33
+ last_position : u32 ,
34
+
27
35
/// Used for debug indentation
28
- depth : Vec < u32 > ,
36
+ ///
37
+ /// Pushes writer positions on the stack
38
+ depth : Vec < Option < u32 > > ,
29
39
30
40
indent_enabled : bool ,
31
41
comment_writer : Box < dyn CommentWriter > ,
@@ -37,13 +47,14 @@ pub struct FinishOutputs<'a> {
37
47
//pub debug_ref: Vec<u8>,
38
48
}
39
49
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 {
43
52
Self {
44
- writer : SliceWriter :: new ( bytes) ,
45
53
debug_ref,
54
+
55
+ last_position : 0 ,
46
56
depth : Vec :: new ( ) ,
57
+
47
58
indent_enabled : true ,
48
59
comment_writer : if comment_xml {
49
60
Box :: new ( XmlCommentWriter :: default ( ) )
@@ -52,6 +63,16 @@ impl<'a> ClarifySliceWriter<'a> {
52
63
} ,
53
64
}
54
65
}
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
+ }
55
76
56
77
// /// Encode a value which impls the [`Encode`] trait.
57
78
// pub fn encode<T: Encode>(&mut self, encodable: &T) -> Result<()> {
@@ -118,13 +139,28 @@ impl<'a> ClarifySliceWriter<'a> {
118
139
// self.error(ErrorKind::Length { tag: Tag::Sequence })
119
140
// }
120
141
// }
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 {
121
151
/// Returns indentation, for example "\n\t" for depth == 1
122
152
pub fn indent_str ( & self ) -> & ' static str {
123
153
let ilen = self . depth . len ( ) * 1 ;
124
154
let ilen = ilen. min ( INDENT_STR . len ( ) ) ;
125
155
& INDENT_STR [ ..ilen]
126
156
}
127
157
158
+ pub fn write_clarify_indent_if_enabled ( & mut self ) {
159
+ if self . indent_enabled {
160
+ self . write_clarify_indent ( ) ;
161
+ }
162
+ }
163
+
128
164
/// Writes indentation to debug output, for example "\n\t" for depth == 1
129
165
pub fn write_clarify_indent ( & mut self ) {
130
166
let indent = self . indent_str ( ) ;
@@ -180,54 +216,36 @@ impl<'a> ClarifySliceWriter<'a> {
180
216
}
181
217
}
182
218
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 ) {
190
221
self . indent_enabled = true ;
191
- self . depth . push ( u32 :: from ( self . writer . position ( ) ) ) ;
222
+ self . depth . push ( writer_pos ) ;
192
223
193
224
let type_name = strip_transparent_types ( type_name) ;
194
225
self . write_clarify_type_str ( "type" , & type_name) ;
195
226
}
196
227
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
+ _ => { }
216
240
}
217
241
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 ( ) ) ;
227
245
}
228
246
229
247
/// 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 ) {
231
249
// just to print a single length byte without indent
232
250
self . indent_enabled = false ;
233
251
}
@@ -240,11 +258,18 @@ impl<'a> Writer for ClarifySliceWriter<'a> {
240
258
// self.indent_enabled = enabled;
241
259
// }
242
260
243
- fn clarify_field_name ( & mut self , field_name : & str ) {
261
+ pub fn clarify_field_name ( & mut self , field_name : & str ) {
244
262
self . write_clarify_indent ( ) ;
245
263
self . write_clarify_type_str ( "field" , field_name) ;
246
264
}
247
265
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
+
248
273
// fn clarify_end_length(&mut self, tag: Option<&Tag>, length: Length) {
249
274
// self.indent_enabled = true;
250
275
// if let Some(tag) = tag {
@@ -264,15 +289,23 @@ impl<'a> Writer for ClarifySliceWriter<'a> {
264
289
// self.write_debug_int(value);
265
290
// }
266
291
267
- fn clarify_choice ( & mut self , choice_name : & [ u8 ] ) {
292
+ pub fn clarify_choice ( & mut self , choice_name : & [ u8 ] ) {
268
293
self . write_clarify_indent ( ) ;
269
294
if let Ok ( choice_name) = std:: str:: from_utf8 ( choice_name) {
270
295
self . write_clarify_type_str ( "CHOICE" , choice_name) ;
271
296
}
272
297
}
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 ;
273
304
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 ( ( ) )
276
309
}
277
310
}
278
311
0 commit comments