@@ -136,6 +136,11 @@ impl FitDataField {
136
136
pub fn into_value ( self ) -> Value {
137
137
self . value
138
138
}
139
+
140
+ /// Consume the field and return the value with associated units
141
+ pub fn into_value_with_units ( self ) -> ValueWithUnits {
142
+ ValueWithUnits :: new ( self . value , self . units )
143
+ }
139
144
}
140
145
141
146
impl fmt:: Display for FitDataField {
@@ -326,7 +331,7 @@ impl convert::TryInto<i64> for &Value {
326
331
/// Describes a field value along with its defined units (if any), this struct is useful for
327
332
/// serializing data in a key-value store where the key is either the name or definition number
328
333
/// since it can be created from a `FitDataField` with minimal data cloning.
329
- #[ derive( Clone , Debug , Serialize ) ]
334
+ #[ derive( Clone , Debug , PartialEq , PartialOrd , Serialize ) ]
330
335
pub struct ValueWithUnits {
331
336
value : Value ,
332
337
units : String ,
@@ -337,6 +342,16 @@ impl ValueWithUnits {
337
342
pub fn new ( value : Value , units : String ) -> Self {
338
343
ValueWithUnits { value, units }
339
344
}
345
+
346
+ /// Return a reference to the stored value
347
+ pub fn value ( & self ) -> & Value {
348
+ & self . value
349
+ }
350
+
351
+ /// Return units associated with the value
352
+ pub fn units ( & self ) -> & str {
353
+ & self . units
354
+ }
340
355
}
341
356
342
357
impl convert:: From < FitDataField > for ValueWithUnits {
@@ -361,104 +376,104 @@ mod tests {
361
376
use super :: * ;
362
377
use std:: collections:: HashSet ;
363
378
379
+ fn validate_records ( records : Vec < FitDataRecord > , ignore_unexpected_fields : bool ) {
380
+ let mut options = MessageParseOptions :: default ( ) ;
381
+ options. ignore_unexpected_fields = ignore_unexpected_fields;
382
+ for record in records {
383
+ validate_record ( record, options) ;
384
+ }
385
+ }
386
+
387
+ fn validate_record ( record : FitDataRecord , options : MessageParseOptions ) {
388
+ if !MesgNum :: is_named_variant ( record. kind ( ) . as_i64 ( ) ) {
389
+ return ;
390
+ }
391
+ let message = Message :: parse_with_options ( record, options) . unwrap ( ) ;
392
+ assert ! (
393
+ message. invalid_fields( ) . is_empty( ) ,
394
+ "{:?}" ,
395
+ message. invalid_fields( )
396
+ ) ;
397
+ }
398
+
364
399
#[ test]
365
400
fn parse_activity ( ) {
366
401
let data = include_bytes ! ( "../tests/fixtures/Activity.fit" ) . to_vec ( ) ;
367
402
let fit_data = from_bytes ( & data) . unwrap ( ) ;
368
403
assert_eq ! ( fit_data. len( ) , 22 ) ;
369
- for record in fit_data {
370
- assert ! ( Message :: parse( record) . is_ok( ) ) ;
371
- }
404
+ validate_records ( fit_data, false ) ;
372
405
}
373
406
374
407
#[ test]
375
408
fn parse_developer_data ( ) {
376
409
let data = include_bytes ! ( "../tests/fixtures/DeveloperData.fit" ) . to_vec ( ) ;
377
410
let fit_data = from_bytes ( & data) . unwrap ( ) ;
378
411
assert_eq ! ( fit_data. len( ) , 6 ) ;
379
- for record in fit_data {
380
- assert ! ( Message :: parse( record) . is_ok( ) ) ;
381
- }
412
+ validate_records ( fit_data, false ) ;
382
413
}
383
414
384
415
#[ test]
385
416
fn parse_monitoring_file ( ) {
386
417
let data = include_bytes ! ( "../tests/fixtures/MonitoringFile.fit" ) . to_vec ( ) ;
387
418
let fit_data = from_bytes ( & data) . unwrap ( ) ;
388
419
assert_eq ! ( fit_data. len( ) , 355 ) ;
389
- for record in fit_data {
390
- assert ! ( Message :: parse( record) . is_ok( ) ) ;
391
- }
420
+ validate_records ( fit_data, false ) ;
392
421
}
393
422
394
423
#[ test]
395
424
fn parse_settings ( ) {
396
425
let data = include_bytes ! ( "../tests/fixtures/Settings.fit" ) . to_vec ( ) ;
397
426
let fit_data = from_bytes ( & data) . unwrap ( ) ;
398
427
assert_eq ! ( fit_data. len( ) , 3 ) ;
399
- for record in fit_data {
400
- assert ! ( Message :: parse( record) . is_ok( ) ) ;
401
- }
428
+ validate_records ( fit_data, false ) ;
402
429
}
403
430
404
431
#[ test]
405
432
fn parse_weight_scale_multi_user ( ) {
406
433
let data = include_bytes ! ( "../tests/fixtures/WeightScaleMultiUser.fit" ) . to_vec ( ) ;
407
434
let fit_data = from_bytes ( & data) . unwrap ( ) ;
408
435
assert_eq ! ( fit_data. len( ) , 7 ) ;
409
- for record in fit_data {
410
- assert ! ( Message :: parse( record) . is_ok( ) ) ;
411
- }
436
+ validate_records ( fit_data, false ) ;
412
437
}
413
438
414
439
#[ test]
415
440
fn parse_weight_scale_single_user ( ) {
416
441
let data = include_bytes ! ( "../tests/fixtures/WeightScaleSingleUser.fit" ) . to_vec ( ) ;
417
442
let fit_data = from_bytes ( & data) . unwrap ( ) ;
418
443
assert_eq ! ( fit_data. len( ) , 6 ) ;
419
- for record in fit_data {
420
- assert ! ( Message :: parse( record) . is_ok( ) ) ;
421
- }
444
+ validate_records ( fit_data, false ) ;
422
445
}
423
446
424
447
#[ test]
425
448
fn parse_workout_custom_target_values ( ) {
426
449
let data = include_bytes ! ( "../tests/fixtures/WorkoutCustomTargetValues.fit" ) . to_vec ( ) ;
427
450
let fit_data = from_bytes ( & data) . unwrap ( ) ;
428
451
assert_eq ! ( fit_data. len( ) , 6 ) ;
429
- for record in fit_data {
430
- assert ! ( Message :: parse( record) . is_ok( ) ) ;
431
- }
452
+ validate_records ( fit_data, false ) ;
432
453
}
433
454
434
455
#[ test]
435
456
fn parse_workout_individual_steps ( ) {
436
457
let data = include_bytes ! ( "../tests/fixtures/WorkoutIndividualSteps.fit" ) . to_vec ( ) ;
437
458
let fit_data = from_bytes ( & data) . unwrap ( ) ;
438
459
assert_eq ! ( fit_data. len( ) , 6 ) ;
439
- for record in fit_data {
440
- assert ! ( Message :: parse( record) . is_ok( ) ) ;
441
- }
460
+ validate_records ( fit_data, false ) ;
442
461
}
443
462
444
463
#[ test]
445
464
fn parse_workout_repeat_greater_than_step ( ) {
446
465
let data = include_bytes ! ( "../tests/fixtures/WorkoutRepeatGreaterThanStep.fit" ) . to_vec ( ) ;
447
466
let fit_data = from_bytes ( & data) . unwrap ( ) ;
448
467
assert_eq ! ( fit_data. len( ) , 7 ) ;
449
- for record in fit_data {
450
- assert ! ( Message :: parse( record) . is_ok( ) ) ;
451
- }
468
+ validate_records ( fit_data, false ) ;
452
469
}
453
470
454
471
#[ test]
455
472
fn parse_workout_repeat_steps ( ) {
456
473
let data = include_bytes ! ( "../tests/fixtures/WorkoutRepeatSteps.fit" ) . to_vec ( ) ;
457
474
let fit_data = from_bytes ( & data) . unwrap ( ) ;
458
475
assert_eq ! ( fit_data. len( ) , 7 ) ;
459
- for record in fit_data {
460
- assert ! ( Message :: parse( record) . is_ok( ) ) ;
461
- }
476
+ validate_records ( fit_data, false ) ;
462
477
}
463
478
464
479
#[ test]
@@ -468,13 +483,7 @@ mod tests {
468
483
let data = include_bytes ! ( "../tests/fixtures/garmin-fenix-5-bike.fit" ) . to_vec ( ) ;
469
484
let fit_data = from_bytes ( & data) . unwrap ( ) ;
470
485
assert_eq ! ( fit_data. len( ) , 143 ) ;
471
- let mut options = MessageParseOptions :: default ( ) ;
472
- options. ignore_unexpected_fields = true ;
473
- for record in fit_data {
474
- if MesgNum :: is_named_variant ( record. kind ( ) . as_i64 ( ) ) {
475
- assert ! ( Message :: parse_with_options( record, options) . is_ok( ) ) ;
476
- }
477
- }
486
+ validate_records ( fit_data, true ) ;
478
487
}
479
488
480
489
#[ test]
@@ -483,13 +492,7 @@ mod tests {
483
492
let data = include_bytes ! ( "../tests/fixtures/sample_mulitple_header.fit" ) . to_vec ( ) ;
484
493
let fit_data = from_bytes ( & data) . unwrap ( ) ;
485
494
assert_eq ! ( fit_data. len( ) , 3023 ) ;
486
- let mut options = MessageParseOptions :: default ( ) ;
487
- options. ignore_unexpected_fields = true ;
488
- for record in fit_data {
489
- if MesgNum :: is_named_variant ( record. kind ( ) . as_i64 ( ) ) {
490
- assert ! ( Message :: parse_with_options( record, options) . is_ok( ) ) ;
491
- }
492
- }
495
+ validate_records ( fit_data, true ) ;
493
496
}
494
497
495
498
#[ test]
0 commit comments