#typed #derive #stringly-typed #stringly

stringly_typed_derive

stringly_typed crate的自定义 derive

1 个不稳定版本

使用旧的 Rust 2015

0.1.0 2018年4月17日

#150 in #typed


stringly_typed 中使用

MIT 许可证

5KB
80

Stringly-Typed Rust

Build Status

一个用于使用字符串类型化API更新值的crate。

典型用法

想象你正在开发一个使用大量运行时配置来改变应用程序行为的系统。由于某种原因,停止整个系统来更新单个配置键并不实际,因此你需要能够动态更新配置...你将如何做?

  • 每次更改都重新上传整个配置文件
  • 调用者发送他们想要更新的键值对,然后通过以下方式执行更新
    • 将序列化为更宽松的类型形式(例如 serde_json::Value),进行更新(例如 config["foo.bar"]["bar"][3] = 42),然后反序列化为原始类型
    • 编写一个switch-case语句,根据提供的键更新不同的字段(例如 match key { "foo.bar" => config.foo.bar = value })

就难度而言,第一个选项相当好。你只需要用 config 包裹一个 RWLock,配置更新问题就消失了,然而你现在需要支付序列化/反序列化和网络传输的代价。此外,复制整个文件来更改一个键可能感觉非常浪费。

待办事项:提及序列化-反序列化很昂贵

待办事项:提及这实际上是在自动化大规模的switch-case语句

#[macro_use]
extern crate stringly_typed;
use stringly_typed::{StringlyTyped, Value};

#[derive(StringlyTyped)]
struct Config {
  motion_parameters: MotionParameters,
  target_bed_temp: f64,
  version: String,
  ...
}

#[derive(StringlyTyped)]
struct MotionParameters {
  max_translation_velocity: f64,
  max_vertical_velocity: f64,
}

// Assume we were told which key and value to update over the network or some
// other dynamic source
let key = "motion_parameters.max_vertical_velocity";
let value = Value::Double(40.0);

cfg.set(key, value)?;
assert_eq!(cfg.motion_parameters.max_vertical_velocity, 40.0);

特性

  • 支持 no_std
  • 支持枚举
  • 支持数组

基准测试

这个crate的主要目标不是性能,然而与“常规”的静态赋值(即使用点运算符的正常Rust)相比,它的表现相当不错,并且仍然优于序列化-更新-反序列化方法。

test static_assign         ... bench:          81 ns/iter (+/- 6)
test stringly_update       ... bench:         167 ns/iter (+/- 12)
test serialize_deserialize ... bench:       1,243 ns/iter (+/- 343)

与任何基准测试一样,我们只比较了三种虚构的使用案例,因此请对这些数据持保留态度。

依赖项

~2MB
~47K SLoC