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 Constraint
s between them.
A Constraint
consists of a set of Method
s 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 Component
s 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.