#reference #nested #fields #keypaths #derivable #compile-time #concepts

keypath

可推导、类型安全的 Swift 风格的 keypaths

3 个不稳定版本

0.2.0 2021 年 6 月 25 日
0.1.1 2021 年 6 月 18 日
0.1.0 2021 年 6 月 15 日

#2419 in Rust 模式


用于 keypath-proc-macros

Apache-2.0

24KB
561

keypath

对任意嵌套字段的强类型引用。

这是在 Rust 中实现 Swift 风格的 keypaths 的早期实验。目前它被视为一个概念验证,缺少一些更复杂的功能,如 '部分 keypaths' 和组合性,尽管实现这些功能应该不会特别困难。它所包含的我认为是最困难的情况,为任意类型生成编译时保证的强类型 keypaths。

这意味着你可以做以下操作

#[derive(Keyable)]
struct Person {
    name: String,
    friends: Vec<String>,
    size: Size,
}
#[derive(Keyable)]
struct Size {
    big: bool,
    heft: u8,
}

let mut person = Person {
    name: "coco".into(),
    friends: vec!["eli".into(), "nico".into(), "yaya".into()],
    size: Size { big: false, heft: 45 }
};

let first_friend: KeyPath<Person, String> = keypath!(Person.friends[0]);
let heft = keypath!(Person.size.heft);

assert_eq!(person[&first_friend], "eli");

// mutation:
person[&heft] = 101;
assert_eq!(person.size.heft, 101);

这本身可能看起来并不特别有用,但它为 UI 绑定和可观察对象等事物提供了一个更舒适的构建块。

待办事项

这里有许多额外的功能和想法值得探索

  • 允许集合访问返回可选值,并具有链式操作: People.friends[10]?.age 允许索引操作失败。
  • 集合的更简单实现(目前是手动的,没有提供 derive)
  • keypath! 宏中支持泛型

依赖

~1.5MB
~38K SLoC