@@ -48,20 +48,29 @@ impl Aim {
4848 }
4949
5050 /// Parse AIM XRK/DRK file from a file path
51- #[ cfg( all( any( target_os = "windows" , target_os = "linux" ) , target_arch = "x86_64" ) ) ]
51+ #[ cfg( all(
52+ any( target_os = "windows" , target_os = "linux" ) ,
53+ target_arch = "x86_64"
54+ ) ) ]
5255 pub fn parse_file ( path : & Path ) -> Result < Log , Box < dyn Error > > {
5356 Self :: parse_file_xdrk ( path)
5457 }
5558
5659 /// Parse AIM XRK/DRK file from a file path (pure Rust implementation for unsupported platforms)
57- #[ cfg( not( all( any( target_os = "windows" , target_os = "linux" ) , target_arch = "x86_64" ) ) ) ]
60+ #[ cfg( not( all(
61+ any( target_os = "windows" , target_os = "linux" ) ,
62+ target_arch = "x86_64"
63+ ) ) ) ]
5864 pub fn parse_file ( path : & Path ) -> Result < Log , Box < dyn Error > > {
5965 let data = std:: fs:: read ( path) ?;
6066 Self :: parse_binary ( & data)
6167 }
6268
6369 /// Parse using xdrk library (Windows/Linux x86_64 only)
64- #[ cfg( all( any( target_os = "windows" , target_os = "linux" ) , target_arch = "x86_64" ) ) ]
70+ #[ cfg( all(
71+ any( target_os = "windows" , target_os = "linux" ) ,
72+ target_arch = "x86_64"
73+ ) ) ]
6574 fn parse_file_xdrk ( path : & Path ) -> Result < Log , Box < dyn Error > > {
6675 // Load the XRK file using xdrk
6776 let run = xdrk:: Run :: load ( path) ?;
@@ -89,7 +98,9 @@ impl Aim {
8998 let mut channels = Vec :: with_capacity ( channel_count) ;
9099
91100 for i in 0 ..channel_count {
92- let name = run. channel_name ( i) . unwrap_or_else ( |_| format ! ( "Channel_{}" , i) ) ;
101+ let name = run
102+ . channel_name ( i)
103+ . unwrap_or_else ( |_| format ! ( "Channel_{}" , i) ) ;
93104 let unit = run. channel_unit ( i) . unwrap_or_default ( ) ;
94105 channels. push ( AimChannel { name, unit } ) ;
95106 }
@@ -116,7 +127,10 @@ impl Aim {
116127 tracing:: warn!( "No samples found in AIM log file" ) ;
117128 return Ok ( Log {
118129 meta : Meta :: Aim ( meta) ,
119- channels : channels. into_iter ( ) . map ( super :: types:: Channel :: Aim ) . collect ( ) ,
130+ channels : channels
131+ . into_iter ( )
132+ . map ( super :: types:: Channel :: Aim )
133+ . collect ( ) ,
120134 times,
121135 data,
122136 } ) ;
@@ -161,21 +175,30 @@ impl Aim {
161175
162176 Ok ( Log {
163177 meta : Meta :: Aim ( meta) ,
164- channels : channels. into_iter ( ) . map ( super :: types:: Channel :: Aim ) . collect ( ) ,
178+ channels : channels
179+ . into_iter ( )
180+ . map ( super :: types:: Channel :: Aim )
181+ . collect ( ) ,
165182 times,
166183 data,
167184 } )
168185 }
169186
170187 /// Parse XRK binary data using pure Rust implementation
171188 /// This is used on platforms where xdrk is not available (macOS, ARM, etc.)
172- #[ cfg( not( all( any( target_os = "windows" , target_os = "linux" ) , target_arch = "x86_64" ) ) ) ]
189+ #[ cfg( not( all(
190+ any( target_os = "windows" , target_os = "linux" ) ,
191+ target_arch = "x86_64"
192+ ) ) ) ]
173193 fn parse_binary ( data : & [ u8 ] ) -> Result < Log , Box < dyn Error > > {
174194 if !Self :: detect ( data) {
175195 return Err ( "Not a valid AIM XRK file" . into ( ) ) ;
176196 }
177197
178- tracing:: info!( "Parsing AIM XRK file using pure Rust implementation ({} bytes)" , data. len( ) ) ;
198+ tracing:: info!(
199+ "Parsing AIM XRK file using pure Rust implementation ({} bytes)" ,
200+ data. len( )
201+ ) ;
179202
180203 // Parse channels from the XRK binary format
181204 let channels = Self :: parse_channels ( data) ?;
@@ -191,14 +214,20 @@ impl Aim {
191214
192215 Ok ( Log {
193216 meta : Meta :: Aim ( meta) ,
194- channels : channels. into_iter ( ) . map ( super :: types:: Channel :: Aim ) . collect ( ) ,
217+ channels : channels
218+ . into_iter ( )
219+ . map ( super :: types:: Channel :: Aim )
220+ . collect ( ) ,
195221 times,
196222 data : channel_data,
197223 } )
198224 }
199225
200226 /// Parse channel definitions from XRK data
201- #[ cfg( not( all( any( target_os = "windows" , target_os = "linux" ) , target_arch = "x86_64" ) ) ) ]
227+ #[ cfg( not( all(
228+ any( target_os = "windows" , target_os = "linux" ) ,
229+ target_arch = "x86_64"
230+ ) ) ) ]
202231 fn parse_channels ( data : & [ u8 ] ) -> Result < Vec < AimChannel > , Box < dyn Error > > {
203232 let mut channels = Vec :: new ( ) ;
204233
@@ -279,7 +308,10 @@ impl Aim {
279308 }
280309
281310 /// Parse metadata from the XRK file footer
282- #[ cfg( not( all( any( target_os = "windows" , target_os = "linux" ) , target_arch = "x86_64" ) ) ) ]
311+ #[ cfg( not( all(
312+ any( target_os = "windows" , target_os = "linux" ) ,
313+ target_arch = "x86_64"
314+ ) ) ) ]
283315 fn parse_metadata ( data : & [ u8 ] ) -> Result < AimMeta , Box < dyn Error > > {
284316 let mut meta = AimMeta :: default ( ) ;
285317
@@ -289,7 +321,8 @@ impl Aim {
289321 if start + 50 < data. len ( ) {
290322 // Skip length bytes and read vehicle name
291323 if let Some ( end) = Self :: find_pattern ( & data[ start..] , b"<" , 0 ) {
292- meta. vehicle = Self :: read_null_terminated_string ( & data[ start + 4 ..] , end. min ( 50 ) ) ;
324+ meta. vehicle =
325+ Self :: read_null_terminated_string ( & data[ start + 4 ..] , end. min ( 50 ) ) ;
293326 }
294327 }
295328 }
@@ -299,7 +332,8 @@ impl Aim {
299332 let start = pos + 5 ;
300333 if start + 100 < data. len ( ) {
301334 if let Some ( end) = Self :: find_pattern ( & data[ start..] , b"<" , 0 ) {
302- meta. championship = Self :: read_null_terminated_string ( & data[ start + 4 ..] , end. min ( 100 ) ) ;
335+ meta. championship =
336+ Self :: read_null_terminated_string ( & data[ start + 4 ..] , end. min ( 100 ) ) ;
303337 }
304338 }
305339 }
@@ -309,7 +343,8 @@ impl Aim {
309343 let start = pos + 5 ;
310344 if start + 50 < data. len ( ) {
311345 if let Some ( end) = Self :: find_pattern ( & data[ start..] , b"<" , 0 ) {
312- meta. venue_type = Self :: read_null_terminated_string ( & data[ start + 4 ..] , end. min ( 50 ) ) ;
346+ meta. venue_type =
347+ Self :: read_null_terminated_string ( & data[ start + 4 ..] , end. min ( 50 ) ) ;
313348 }
314349 }
315350 }
@@ -318,8 +353,14 @@ impl Aim {
318353 }
319354
320355 /// Parse channel data samples from )(G records
321- #[ cfg( not( all( any( target_os = "windows" , target_os = "linux" ) , target_arch = "x86_64" ) ) ) ]
322- fn parse_channel_data ( data : & [ u8 ] , channel_count : usize ) -> Result < ( Vec < f64 > , Vec < Vec < Value > > ) , Box < dyn Error > > {
356+ #[ cfg( not( all(
357+ any( target_os = "windows" , target_os = "linux" ) ,
358+ target_arch = "x86_64"
359+ ) ) ) ]
360+ fn parse_channel_data (
361+ data : & [ u8 ] ,
362+ channel_count : usize ,
363+ ) -> Result < ( Vec < f64 > , Vec < Vec < Value > > ) , Box < dyn Error > > {
323364 let mut times = Vec :: new ( ) ;
324365 let mut all_data: Vec < Vec < Value > > = Vec :: new ( ) ;
325366
@@ -340,8 +381,7 @@ impl Aim {
340381 while offset + 20 < data. len ( ) {
341382 if let Some ( pos) = Self :: find_pattern ( data, marker, offset) {
342383 // Find the next marker to determine record size
343- let next_pos = Self :: find_pattern ( data, b")(" , pos + 3 )
344- . unwrap_or ( data. len ( ) ) ;
384+ let next_pos = Self :: find_pattern ( data, b")(" , pos + 3 ) . unwrap_or ( data. len ( ) ) ;
345385 let record_size = next_pos - pos;
346386
347387 // Process records in the typical telemetry size range (100-200 bytes)
@@ -441,14 +481,9 @@ impl Aim {
441481 /// Read a null-terminated string from a byte slice, up to max_len bytes
442482 fn read_null_terminated_string ( data : & [ u8 ] , max_len : usize ) -> String {
443483 let max = max_len. min ( data. len ( ) ) ;
444- let end = data[ ..max]
445- . iter ( )
446- . position ( |& b| b == 0 )
447- . unwrap_or ( max) ;
448-
449- String :: from_utf8_lossy ( & data[ ..end] )
450- . trim ( )
451- . to_string ( )
484+ let end = data[ ..max] . iter ( ) . position ( |& b| b == 0 ) . unwrap_or ( max) ;
485+
486+ String :: from_utf8_lossy ( & data[ ..end] ) . trim ( ) . to_string ( )
452487 }
453488}
454489
@@ -543,7 +578,11 @@ mod tests {
543578
544579 // Verify detection
545580 let data = std:: fs:: read ( & path) . expect ( "Failed to read file" ) ;
546- assert ! ( Aim :: detect( & data) , "Should detect {} as XRK format" , path. display( ) ) ;
581+ assert ! (
582+ Aim :: detect( & data) ,
583+ "Should detect {} as XRK format" ,
584+ path. display( )
585+ ) ;
547586
548587 // Parse the file
549588 match Aim :: parse_file ( & path) {
@@ -552,9 +591,21 @@ mod tests {
552591 eprintln ! ( " Data records: {}" , log. data. len( ) ) ;
553592
554593 // Verify we got actual data
555- assert ! ( !log. channels. is_empty( ) , "Should have channels for {}" , path. display( ) ) ;
556- assert ! ( !log. data. is_empty( ) , "Should have data records for {}" , path. display( ) ) ;
557- assert ! ( !log. times. is_empty( ) , "Should have timestamps for {}" , path. display( ) ) ;
594+ assert ! (
595+ !log. channels. is_empty( ) ,
596+ "Should have channels for {}" ,
597+ path. display( )
598+ ) ;
599+ assert ! (
600+ !log. data. is_empty( ) ,
601+ "Should have data records for {}" ,
602+ path. display( )
603+ ) ;
604+ assert ! (
605+ !log. times. is_empty( ) ,
606+ "Should have timestamps for {}" ,
607+ path. display( )
608+ ) ;
558609
559610 if !log. times . is_empty ( ) {
560611 eprintln ! (
@@ -565,10 +616,15 @@ mod tests {
565616 }
566617
567618 // Verify data has actual values
568- let has_non_zero = log. data . iter ( ) . any ( |row| {
569- row. iter ( ) . any ( |v| v. as_f64 ( ) . abs ( ) > 0.0001 )
570- } ) ;
571- assert ! ( has_non_zero, "Should have non-zero values for {}" , path. display( ) ) ;
619+ let has_non_zero = log
620+ . data
621+ . iter ( )
622+ . any ( |row| row. iter ( ) . any ( |v| v. as_f64 ( ) . abs ( ) > 0.0001 ) ) ;
623+ assert ! (
624+ has_non_zero,
625+ "Should have non-zero values for {}" ,
626+ path. display( )
627+ ) ;
572628
573629 parsed_count += 1 ;
574630 }
0 commit comments