@@ -136,6 +136,11 @@ impl FitDataField {
136136 pub fn into_value ( self ) -> Value {
137137 self . value
138138 }
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+ }
139144}
140145
141146impl fmt:: Display for FitDataField {
@@ -326,7 +331,7 @@ impl convert::TryInto<i64> for &Value {
326331/// Describes a field value along with its defined units (if any), this struct is useful for
327332/// serializing data in a key-value store where the key is either the name or definition number
328333/// since it can be created from a `FitDataField` with minimal data cloning.
329- #[ derive( Clone , Debug , Serialize ) ]
334+ #[ derive( Clone , Debug , PartialEq , PartialOrd , Serialize ) ]
330335pub struct ValueWithUnits {
331336 value : Value ,
332337 units : String ,
@@ -337,6 +342,16 @@ impl ValueWithUnits {
337342 pub fn new ( value : Value , units : String ) -> Self {
338343 ValueWithUnits { value, units }
339344 }
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+ }
340355}
341356
342357impl convert:: From < FitDataField > for ValueWithUnits {
@@ -361,104 +376,104 @@ mod tests {
361376 use super :: * ;
362377 use std:: collections:: HashSet ;
363378
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+
364399 #[ test]
365400 fn parse_activity ( ) {
366401 let data = include_bytes ! ( "../tests/fixtures/Activity.fit" ) . to_vec ( ) ;
367402 let fit_data = from_bytes ( & data) . unwrap ( ) ;
368403 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 ) ;
372405 }
373406
374407 #[ test]
375408 fn parse_developer_data ( ) {
376409 let data = include_bytes ! ( "../tests/fixtures/DeveloperData.fit" ) . to_vec ( ) ;
377410 let fit_data = from_bytes ( & data) . unwrap ( ) ;
378411 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 ) ;
382413 }
383414
384415 #[ test]
385416 fn parse_monitoring_file ( ) {
386417 let data = include_bytes ! ( "../tests/fixtures/MonitoringFile.fit" ) . to_vec ( ) ;
387418 let fit_data = from_bytes ( & data) . unwrap ( ) ;
388419 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 ) ;
392421 }
393422
394423 #[ test]
395424 fn parse_settings ( ) {
396425 let data = include_bytes ! ( "../tests/fixtures/Settings.fit" ) . to_vec ( ) ;
397426 let fit_data = from_bytes ( & data) . unwrap ( ) ;
398427 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 ) ;
402429 }
403430
404431 #[ test]
405432 fn parse_weight_scale_multi_user ( ) {
406433 let data = include_bytes ! ( "../tests/fixtures/WeightScaleMultiUser.fit" ) . to_vec ( ) ;
407434 let fit_data = from_bytes ( & data) . unwrap ( ) ;
408435 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 ) ;
412437 }
413438
414439 #[ test]
415440 fn parse_weight_scale_single_user ( ) {
416441 let data = include_bytes ! ( "../tests/fixtures/WeightScaleSingleUser.fit" ) . to_vec ( ) ;
417442 let fit_data = from_bytes ( & data) . unwrap ( ) ;
418443 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 ) ;
422445 }
423446
424447 #[ test]
425448 fn parse_workout_custom_target_values ( ) {
426449 let data = include_bytes ! ( "../tests/fixtures/WorkoutCustomTargetValues.fit" ) . to_vec ( ) ;
427450 let fit_data = from_bytes ( & data) . unwrap ( ) ;
428451 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 ) ;
432453 }
433454
434455 #[ test]
435456 fn parse_workout_individual_steps ( ) {
436457 let data = include_bytes ! ( "../tests/fixtures/WorkoutIndividualSteps.fit" ) . to_vec ( ) ;
437458 let fit_data = from_bytes ( & data) . unwrap ( ) ;
438459 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 ) ;
442461 }
443462
444463 #[ test]
445464 fn parse_workout_repeat_greater_than_step ( ) {
446465 let data = include_bytes ! ( "../tests/fixtures/WorkoutRepeatGreaterThanStep.fit" ) . to_vec ( ) ;
447466 let fit_data = from_bytes ( & data) . unwrap ( ) ;
448467 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 ) ;
452469 }
453470
454471 #[ test]
455472 fn parse_workout_repeat_steps ( ) {
456473 let data = include_bytes ! ( "../tests/fixtures/WorkoutRepeatSteps.fit" ) . to_vec ( ) ;
457474 let fit_data = from_bytes ( & data) . unwrap ( ) ;
458475 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 ) ;
462477 }
463478
464479 #[ test]
@@ -468,13 +483,7 @@ mod tests {
468483 let data = include_bytes ! ( "../tests/fixtures/garmin-fenix-5-bike.fit" ) . to_vec ( ) ;
469484 let fit_data = from_bytes ( & data) . unwrap ( ) ;
470485 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 ) ;
478487 }
479488
480489 #[ test]
@@ -483,13 +492,7 @@ mod tests {
483492 let data = include_bytes ! ( "../tests/fixtures/sample_mulitple_header.fit" ) . to_vec ( ) ;
484493 let fit_data = from_bytes ( & data) . unwrap ( ) ;
485494 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 ) ;
493496 }
494497
495498 #[ test]
0 commit comments