stringly_typed 0.1.0

A crate for updating values and indexing into Rust types at runtime
Documentation
# Stringly-Typed Rust

[![Build Status](https://travis-ci.org/Michael-F-Bryan/stringly-typed.svg?branch=master)](https://travis-ci.org/Michael-F-Bryan/stringly-typed)

A crate for updating values using a stringly-typed API.

## Typical Use Case

Imagine you're working on a system that uses a lot of runtime configuration to
alter the behaviour of the application. For whatever reason it isn't practical
to stop the entire system just to update a single configuration key, so you need
the ability to update configuration on the fly... How do you do it?

- Re-upload the entire configuration file for every change
- The caller sends just the key-value pair they want to update and you execute 
  the update by:
  - Serializing to a more loosly-typed form (e.g. `serde_json::Value`), make the
    update (e.g. `config["foo"]["bar"][3] = 42`), then deserialize back to the
    original type
  - Write a massive switch-case statement which will update different fields
    depending on the provided key (e.g. `match key { "foo.bar" => config.foo.bar = value }`)

In terms of difficulty the first option is quite nice. You just wrap your 
`config` with a `RWLock` and all your configuration update issues go away, 
however you now pay the price of serializing/deserializing and network transfer.
Plus it can feel awfully wasteful to copy around an entire file just to change
one key.

TODO: Mention how serialize-deserialize is expensive

TODO: Mention this is essentially automating the massive switch-case statement

```rust
#[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);
```

## Features

- [x] Works with `no_std`
- [ ] Supports enums
- [ ] Supports arrays

## Benchmarks

The main goal of this crate *isn't* performance, however it performs quite well
compared to the "usual" static assignment (i.e. normal Rust with the dot
operator), and still beats the serialize-update-deserialize method.

```text
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)
```

As with any benchmark, we're only comparing three contrived use cases so take
these numbers with a grain of salt.