#fit #filesystem #file #decoding #reading #devices #io

fit_no_io

一个用于读取和解析由运动设备生成的FIT文件的小型库,无需文件系统即可工作

1个不稳定版本

0.1.0 2019年7月13日

#2377 in 解析器实现

MIT 许可证

4.5MB
1K SLoC

Fit (no IO)

这是由 fit 的 Richard Brodie 编写的一个适合WebAssembly的适配版本。原始库依赖于文件系统的存在,意味着它不能在像WebAssembly这样的环境中使用,因为这些环境不支持文件系统。这个库要求您将数据直接传递给解析器,而不是将文件路径传递给解析器,因此消除了对文件系统的需求。

原始描述(由Brodie编写)

Fit是一个用于读取和解析由各种运动设备生成的FIT文件的小型库。目前它只被设计为读取Garmin Edges 1000和520以及Wahoo Elemnt生成的文件。它可能会在其他文件源上工作得很好,但除非它是Garmin自行车电脑,否则可能不会100%完美地工作。目前它不支持使用自定义开发字段生成的FIT文件。

有关FIT的更多信息,请参阅ANT SDK(此存储库中包含ZIP存档)。

安装

[dependencies]
fit_no_io = "0.1"

使用方法

extern crate env_logger;
extern crate fit_no_io;

use std::path::PathBuf;
use fit::{self as fit, Message};

fn main() {
    let file = File::open("fits/2913547417.fit").expect("should be able to open file");
    let mut buf = Vec::new();
    file.read(&mut buf).expect("should be able to read file");
    let f: Vec<Message> = fit::run(&buf);
    println!("{:#?}", f);
}

一个典型的 Message 可能看起来像这样

Message {
  kind: Record,
  values: [
    DataField { field_num: 253, value: Time(1480856114) },
    DataField { field_num: 0,   value: F32(57.710945)   },
    DataField { field_num: 1,   value: F32(11.9945755)  },
    DataField { field_num: 5,   value: U32(1151)        },
    DataField { field_num: 29,  value: U32(0)           },
    DataField { field_num: 2,   value: U16(2394)        },
    DataField { field_num: 6,   value: U16(0)           },
    DataField { field_num: 7,   value: U16(0)           },
    DataField { field_num: 61,  value: U16(2234)        },
    DataField { field_num: 66,  value: I16(442)         },
    DataField { field_num: 3,   value: U8(113)          },
    DataField { field_num: 13,  value: I8(21)           }
  ],
  dev_values: []
}

Fit 快速入门

如果您已经非常熟悉FIT文件格式,您可能应该跳过这一部分。否则,请继续阅读。

警告

这是一个快速入门(即,过于简化的戏剧性简化),不是FIT的全面指南。要获取更详细的指南,请参阅ANT FIT SDK。

现在,您已经得到了警告...

基本上,FIT文件是一个Message列表。每个Message基本上就是一个关联键和值的对象/哈希表/字典/您想叫什么就什么。

存在许多种类的 Message。每种 kind 都有不同的用途,并且每种都有自己的形状(即,它们具有哪些属性)。例如,一个 UserProfile Message 将具有与 Record Message 不同的属性。也就是说,UserProfile Message 可能包含有关用户身高和体重的信息,而 Record Message 可能包含有关用户在特定时间点的心率速度等信息。

理想情况下,Rust 中的 Message 应该看起来像这样

struct Message {
  kind: MessageType,
  values: HashMap<Attribute, Value>,
}

enum Attribute {
  Timestamp,
  Distance,
  Speed,
  HeartRate,
  Cadence,
  // ...
}

// `Value` will be explained later

实际上,由于 FIT 的工作方式,它看起来更像是这样

struct Message {
  kind: MessageType,
  values: Vec<DataField>,
}

DataField 是一个键值对。它与您用于构建 HashMap 的键值对相似(即,当您从元组的迭代器构建 HashMap 时 vec![(key1, value1), (key2, value2), ...].into_iter().collect()),但区别在于,它不使用实际的键,而是 DataField 有一个 field_num 成员,可以与 Messagekind 结合使用,以确定实际的键。这样做的原因是不同的 kind 类型的 Message 对于给定 field_num 指的是什么键有不同的规则。例如,Record Message 的字段 0 是用户的纬度,而 DeviceInfo Message 的字段 0 是设备索引。有关 field_numMessage kind 到属性的映射表,请参阅 ANT FIT SDK。

Value 枚举是围绕 Rust 原始类型(如 u16、i64 或 f32)的简单包装。

需要注意的一些事项

  • 速度以 m/s 记录,而不是 kph。
  • 对于跑步,步频以每分钟周期数记录,而不是每分钟步数。一个周期定义为左脚一步加上右脚一步。如果您的步频列出的为 90,则表示每分钟 90 个周期,等于每分钟 180 步。

贡献

原始 crate 的存储库:https://github.com/richardbrodie/fit-rs

此 crate 的存储库:https://github.com/kylejlin/fit_no_io

感谢

感谢 Richard Brodie 开发原始 crate。此 crate 的 99% 来自他的 fit

依赖关系