4个版本

0.1.3 2021年5月4日
0.1.2 2021年4月28日
0.1.1 2021年4月14日
0.1.0 2021年4月14日

#1205 in 算法


hotdrink-wasm中使用

MIT/Apache

300KB
7K SLoC

hotdrink-rs

HotDrink在Rust中的实现。

HotDrink允许您声明性地描述值之间的关系以及如何强制执行它们,然后可以在变量值发生变化时自动执行。

Crates.io docs.rs

简介

在开始之前,这里简要介绍一些术语及其工作原理。一个Component是一组变量及其之间的一组Constraint。一个Constraint由一组Method组成,这些方法本质上是函数,通过从Component的某些变量子集中读取并写入另一个变量来强制执行约束。可以在ConstraintSystem中收集Components,它提供了一个API,可以同时与多个Component交互,例如update

组件

组件是一组变量及其之间应该强制执行的约束。可以通过使用component!宏轻松创建,如下面的示例所示。

约束

约束代表我们要维护的变量之间的关系。它包含一组描述如何执行此操作的约束满足方法。在示例中,我们希望始终保持关系 a + b = c。强制执行它的方法之一是重新计算 a + b 并将 c 设置为该值。

方法

约束满足方法描述了强制执行约束的一种方法。它读取某些变量的值,并将它们写入其他变量。

用法

将以下内容添加到您的Cargo.toml

hotdrink-rs = "0.1.1"

然后您就可以开始了!

use hotdrink_rs::{component, model::ConstraintSystem, ret, Event};

// Define a set of variables and relations between them
let mut component = component! {
    // Define a component `Component`.
    component Component {
        // Define variables and their default values.
        // The value can be omitted for any type that implements `Default`.
        let a: i32 = 0, b: i32, c: i32 = 3;
        // Define a constraint `Sum` that must hold between variables.
        constraint Sum {
            // Provide three ways to enforce the constraint.
            // Only one will be selected, so each one *MUST* enforce the constraint.
            abc(a: &i32, b: &i32) -> [c] = ret![*a + *b];
            acb(a: &i32, c: &i32) -> [b] = ret![*c - *a];
            bca(b: &i32, c: &i32) -> [a] = ret![*c - *b];
        }
    }
};

// Describe what should happen when `a` changes.
component.subscribe("a", |event| match event {
    Event::Pending => println!("A new value for `a` is being computed"),
    Event::Ready(value) => println!("New value for `a`: {}", value),
    Event::Error(errors) => println!("Computation for `a` failed: {:?}", errors),
});

// Change the value of `a`
component.set_variable("a", 3);

// 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 = ConstraintSystem::new();
cs.add_component(component);

// Update every component in the constraint system.
cs.update();

示例

该项目使用多个nightly功能,必须使用nightly Rust构建。我建议使用rustup,可以从此处下载。

./examples 中的示例可以通过以下命令运行:cargo run --example <名称>

许可证

根据以下许可证之一授权

由您选择。

贡献

除非您明确声明,否则根据Apache-2.0许可证定义的您有意提交的任何贡献,都应按上述方式双重许可,无需任何额外的条款或条件。

依赖关系

~2.3–3MB
~66K SLoC