3个版本

0.1.9 2021年9月12日
0.1.8 2021年4月23日
0.1.0 2021年3月31日

#1179 in 异步

MIT 许可证

16KB
430

Fates

Crates.io license Crates.io

此crate提供Fate类型,可用于创建线程安全的响应式声明。依赖其他Fate值的Fate实例将在依赖项更改时自动更新其值。该crate还包括用于自动创建和更新Fate实例的宏。

免责声明:非常初版,可能存在错误,肯定会有变化。

示例

更新文本

fate! {
  [name] // Name will be accessed as a Fate value
    
  // All assignments in the macro will be treated as Fate types
  let name = "Alex".to_string();
  let hello = "Hello, ".to_string() + &name;
  let goodbye = "Goodbye, ".to_string() + &name;
}
assert_eq!(&hello.get(), "Hello, Alex");
assert_eq!(&goodbye.get(), "Goodbye, Alex");

fate! {name = "Sam".to_string();}
assert_eq!(&hello.get(), "Hello, Sam");
assert_eq!(&goodbye.get(), "Goodbye, Sam");

数学表达式

use fates::{fate, Fate};

fate! {
  [a] // a is accessed as a Fate type.
  let a = 5;
  let b = a * 3;
}
assert_eq!(b.get(), 15);
fate! {a = 7;}
assert_eq!(a.get(), 7);
assert_eq!(b.get(), 21);

复制类型

let a = 1;
let b = 10;
let c = 15;
fate! {
  [d]
  let d = a + b; // 1 + 10
  let e = d * c; // 11 * 15
}
assert_eq!(e.get(), 11 * 15);
fate! {d = a;}
assert_eq!(e.get(), 15);

通过引用访问或修改绑定值

fate! {
  let a = vec![1, 2, 3];
}
assert_eq!(a.get(), vec![1, 2, 3]);

a.by_ref_mut(|a| a.push(4));
assert_eq!(a.get(), vec![1, 2, 3, 4]);

let mut val = 2;
a.by_ref(|a| val = a[2]);
assert_eq!(val, 3);

如果表达式被绑定,by_ref / by_ref_mut 不会运行提供的函数。您可以检查此情况

fate! {
    [a]
    let a = 5;
    let b = a * 5;
}

{
    let mut is_value = false;
    a.by_ref_mut(|_a| {
    is_value = true;
    });
    assert_eq!(is_value, true);
}
{
    let mut is_value = false;
    b.by_ref_mut(|_b| {
    is_value = true;
    });
    assert_eq!(is_value, false);
}

存储和手动更新Fate实例

struct TestStruct {
  fate: Fate<i32>,
}
fate! {
  let a = 10;
}

let test_struct = TestStruct { fate: a.clone() };
assert_eq!(a.get(), 10);

fate! {a = 15;}
assert_eq!(test_struct.fate.get(), 15);

// Alternatively:
a.bind_value(200);
assert_eq!(test_struct.fate.get(), 200);

检查值何时已更新

fate! {
    [a]
    let a = 5;
    let b = a + 3;
}
let child = b.create_dependent_clone();
assert_eq!(child.get(), 8);
fate! {
    a = 10;
}
assert_eq!(b.get(), 13);
assert_eq!(b.is_dirty(), false);
// Even though b is no longer dirty, the dependent clone is still dirty.
// This can be used to do something locally whenever the Fate is updated.
assert_eq!(child.is_dirty(), true);
assert_eq!(child.get(), 13);
assert_eq!(child.is_dirty(), false);

灵感来源

依赖关系

~1.6–2.2MB
~47K SLoC