30
30
//! [csv](https://crates.io/crates/csv) crate.
31
31
32
32
use crate :: {
33
+ frame:: Frame ,
33
34
id:: { id_from_raw, FdFlags } ,
34
35
CanAnyFrame , CanDataFrame , CanFdFrame , CanFrame , CanRemoteFrame , ConstructionError ,
35
36
} ;
36
- use embedded_can:: Frame ;
37
+ use embedded_can:: Frame as EmbeddedFrame ;
37
38
use hex:: FromHex ;
39
+ use itertools:: Itertools ;
38
40
use libc:: canid_t;
39
41
use std:: {
42
+ fmt,
40
43
fs:: File ,
41
44
io:: { self , BufRead , BufReader } ,
42
45
path:: Path ,
43
- str,
44
46
} ;
45
47
use thiserror:: Error ;
46
48
@@ -69,16 +71,45 @@ pub enum ParseError {
69
71
70
72
/// Recorded CAN frame.
71
73
/// This corresponds to the information in a line from the candump log.
72
- #[ derive( Debug ) ]
73
- pub struct CanDumpRecord < ' a > {
74
+ #[ derive( Debug , Clone ) ]
75
+ pub struct CanDumpRecord {
74
76
/// The timestamp
75
77
pub t_us : u64 ,
76
78
/// The name of the device
77
- pub device : & ' a str ,
79
+ pub device : String ,
78
80
/// The parsed frame
79
81
pub frame : CanAnyFrame ,
80
82
}
81
83
84
+ impl fmt:: Display for CanDumpRecord {
85
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
86
+ write ! (
87
+ f,
88
+ "({:.6}) {} {:03X}" ,
89
+ 1.0e-6 * self . t_usas f64 ,
90
+ self . device,
91
+ self . frame. raw_id( )
92
+ ) ?;
93
+
94
+ use CanAnyFrame :: * ;
95
+ match self . frame {
96
+ Normal ( frame) =>{
97
+ let mut parts = frame. data ( ) . iter ( ) . map ( |v|format ! ( "{:02X}" , v) ) ;
98
+ write ! ( f, "#{}" , parts. join( "" ) )
99
+ }
100
+ Remote ( frame) if frame. len ( ) ==0 => f. write_str ( "#R" ) ,
101
+ Remote ( frame) =>{
102
+ write ! ( f, "#R{}" , frame. dlc( ) )
103
+ }
104
+ Error ( _frame) => f. write_str ( "" ) ,
105
+ Fd ( frame) =>{
106
+ let mut parts = frame. data ( ) . iter ( ) . map ( |v|format ! ( "{:02X}" , v) ) ;
107
+ write ! ( f, "##{}" , parts. join( "" ) )
108
+ }
109
+ }
110
+ }
111
+ }
112
+
82
113
/////////////////////////////////////////////////////////////////////////////
83
114
// Reader
84
115
@@ -110,10 +141,16 @@ impl Reader<File> {
110
141
111
142
impl < R : BufRead > Reader < R > {
112
143
/// Returns an iterator over all records
113
- pub fn records ( & mut self ) ->CanDumpIter < R > {
114
- CanDumpIter { src : self }
144
+ #[ deprecated( since ="3.5.0" , note ="Use `iter()`" ) ]
145
+ pub fn records ( & mut self ) ->CanDumpRecords < R > {
146
+ CanDumpRecords { src : self }
115
147
}
116
148
149
+ /// Returns an iterator over all records
150
+ // pub fn iter(&mut self) -> CanDumpIter<R> {
151
+ // CanDumpIter { src: self }
152
+ // }
153
+
117
154
/// Advance state, returning next record.
118
155
pub fn next_record ( & mut self ) ->Result < Option < CanDumpRecord > , ParseError > {
119
156
self . buf . clear ( ) ;
@@ -151,7 +188,10 @@ impl<R: BufRead> Reader<R> {
151
188
} ;
152
189
153
190
// device name
154
- let device = field_iter. next ( ) . ok_or ( ParseError :: UnexpectedEndOfLine ) ?;
191
+ let device = field_iter
192
+ . next ( )
193
+ . ok_or ( ParseError :: UnexpectedEndOfLine ) ?
194
+ . to_string ( ) ;
155
195
156
196
// parse packet
157
197
let can_raw = field_iter. next ( ) . ok_or ( ParseError :: UnexpectedEndOfLine ) ?;
@@ -206,13 +246,26 @@ impl<R: BufRead> Reader<R> {
206
246
}
207
247
}
208
248
209
- /// Record iterator
249
+ impl < R : BufRead > Iterator for Reader < R > {
250
+ type Item =Result < CanDumpRecord , ParseError > ;
251
+
252
+ fn next ( & mut self ) ->Option < Self :: Item > {
253
+ // lift Option:
254
+ match self . next_record ( ) {
255
+ Ok ( Some ( rec) ) =>Some ( Ok ( rec) ) ,
256
+ Ok ( None ) =>None ,
257
+ Err ( e) =>Some ( Err ( e) ) ,
258
+ }
259
+ }
260
+ }
261
+
262
+ /// Original Record iterator
210
263
#[ derive( Debug ) ]
211
- pub struct CanDumpIter < ' a , R : ' a > {
264
+ pub struct CanDumpRecords < ' a , R : ' a > {
212
265
src : & ' a mut Reader < R > ,
213
266
}
214
267
215
- impl < R : io:: Read > Iterator for CanDumpIter < ' _ , BufReader < R > > {
268
+ impl < R : io:: Read > Iterator for CanDumpRecords < ' _ , BufReader < R > > {
216
269
type Item =Result < ( u64 , CanAnyFrame ) , ParseError > ;
217
270
218
271
fn next ( & mut self ) ->Option < Self :: Item > {
@@ -225,12 +278,6 @@ impl<R: io::Read> Iterator for CanDumpIter<'_, BufReader<R>> {
225
278
}
226
279
}
227
280
228
- // TODO: Remove in the next major version update
229
- /// Obsolete iterator name, now called `CanDumpIter`
230
- #[ allow( type_alias_bounds) ]
231
- #[ deprecated( since="3.5.0" , note="Renamed to `CanDumpIter`" ) ]
232
- pub type CanDumpRecords < ' a , R : ' a > =CanDumpIter < ' a , R > ;
233
-
234
281
/////////////////////////////////////////////////////////////////////////////
235
282
236
283
#[ cfg( test) ]