fit-sdk-rust
Pure-Rust decoder and encoder for Garmin FIT (Flexible and Interoperable Data Transfer) protocol files — activities, workouts, courses, settings, and more.
Supports FIT protocol v2.0 (profile v21.200). No unsafe code, no C dependencies.
Features
- Streaming decoder — iterator-based, yields one raw message per record
- Typed decoder — profile-aware pipeline with configurable transforms:
- DateTime conversion (
chrono::DateTime<Utc>) - Enum int-to-string resolution (e.g.
"running"forSport::Running) - Scale/offset → physical values
- SubField selection and Component unpacking
- Developer field resolution
- Heart-rate merge and MemoGlob reassembly (post-processing)
- DateTime conversion (
- Encoder — round-trips typed messages back to protocol-compliant FIT binary
- CRC integrity verification — header and file-level
- Multi-FIT chain — transparently handles concatenated FIT files
- Compressed timestamps — full protocol §2.3 support
Quick start
Add to your Cargo.toml:
[]
= "0.2"
The library is exposed under the crate name fit (per [lib] name), so you use fit::... in your code.
Decode an activity file
use Decoder;
let bytes = read?;
// Decode with all transforms enabled (default).
let = builder.build.read_all;
assert!;
for msg in &messages
# Ok::
Access specific fields
use ;
let bytes = read?;
let = builder.build.read_all;
// Find record messages and read heart rate / speed.
for msg in &messages
# Ok::
Encode messages back to FIT
use ;
let bytes = read?;
let = builder.build.read_all;
let encoded: = new.encode?;
check_integrity?;
# Ok::
Raw (low-level) decoding
For streaming or memory-constrained scenarios, use the raw decoder directly:
use Decoder;
let bytes = read?;
let = new.read_all;
for msg in &raw_messages
# Ok::
Configure transform options
Disable individual transforms for cheaper or less opinionated output:
use Decoder;
let bytes = read?;
let = builder
.convert_datetime // keep raw u32 timestamps
.convert_types_to_strings // keep raw enum integers
.apply_scale_and_offset // keep raw integer values
.expand_components // skip component unpacking
.build
.read_all;
# Ok::
Verify file integrity
use ;
let bytes = read?;
if is_fit
# Ok::
API overview
| Type | Purpose |
|---|---|
Decoder |
Streaming raw-message iterator |
DecoderBuilder / TypedDecoder |
Profile-aware typed pipeline |
Encoder / EncoderBuilder |
Encode messages back to FIT binary |
Message |
Fully-transformed message with named fields |
Value |
Typed field value (float, string, enum, datetime, ...) |
Field |
Named field with value, kind, and units |
FitError |
Unified error type |
is_fit / check_integrity |
File-level validation |
MSRV
Rust 1.75 or later.
License
Licensed under the Apache License, Version 2.0. See LICENSE for details.