hotdrink-rs
HotDrink implemented in Rust.
HotDrink lets you describe relations between values declaratively and how to enforce them, and can then automatically do so when the value of a variable changes.
Introduction
Before getting started, here is a quick introduction to the terminology and how it works.
A Component is a set of variables with a set of Constraints between them.
A Constraint consists of a set of Methods that are essentially functions that enforce the constraint
by reading from some subset of the variables of the Component and writing to another.
Components can be gathered in a ConstraintSystem, which provides an API
for interacting with multiple Components at once, such as update.
Components
A component is a collection of variables and constraints between them that should be enforced.
One can easily be created by using the [component!] macro, as shown in the example below.
Constraints
A constraint represents a relation between variables we want to maintain.
It contains a collection of constraint satisfaction methods that describe the different ways to do so.
In the example, we want the relation a + b = c to hold at all times.
One way to enforce it is to re-compute a + b and set c to that value.
Methods
A constraint satisfaction method describes one way to enforce a constraint. It reads the values of some variables, and write to others.
Usage
Add the following to your Cargo.toml:
hotdrink-rs = "0.1.1"
Then you are ready to begin!
use ;
// Define a set of variables and relations between them
let mut component = component! ;
// Describe what should happen when `a` changes.
component.subscribe;
// Change the value of `a`
component.set_variable;
// Enforce all the constraints by selecting a method for each one,
// and then executing the methods in topological order.
component.update;
// Add the component to a constraint system.
// One constraint system can contain many components.
let mut cs = new;
cs.add_component;
// Update every component in the constraint system.
cs.update;
Examples
The project uses multiple nightly features, and must be built using nightly Rust.
I recommend using rustup, which can be downloaded here.
The examples in ./examples can then be run with cargo run --example <name>.
License
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.