1 个不稳定版本
0.1.1 | 2019年2月21日 |
---|---|
0.1.0 |
|
9 在 #street
52KB
322 行
本软件包的目的是以方便、高效、函数式和 Rust 友好的方式提供访问和更新嵌套不可变数据结构(容器)内部字段的光学。
虽然 photonix 受到函数式透镜库的启发,但它采取了不同的方法。在这里,您拥有单方法类型类,它提供了使用灵活性,并使目标数据结构成为自己的透镜,这将遵守 透镜定律。
这种方法有一些后果。首先,您不需要在内存中存储透镜对象。其次,为了拥有这种功能,您不需要定义和处理闭包。第三,与传统的透镜(依赖于函数组合)相比,组合是以不同的方式实现的。
组合功能是通过在 composites
模块中定义的附加特性提供的。通过使用组合特性,您可以深入到实现数据结构的几个级别。这些特性具有默认实现,因此如果您想使用它们,您只需要编写一个空的 impl 块(或使用 zoom!
或 zoom_all!
宏)。
然而,photonix的真正实力在于其元编程功能。该库包含大多数它定义的基本特质的自动推导(photonix_derive
)。自动推导的实现默认避免了数据的克隆。此外,zoom!
和zoom_all!
宏可以帮助您以简洁、直接和易于阅读的方式获得多个组合特质的实现。
示例
一个快速示例(受Monocle
启发)。
// We have a complex data structure
# use photonix::*;
#[derive(Get, GetRef, Set, Modify)]
pub struct Employee { pub name: String, pub company: Company }
#[derive(Get, GetRef, Set, Modify)]
pub struct Company { pub name: String, pub address: Address }
#[derive(Get, GetRef, Set, Modify)]
pub struct Address { pub city: String, pub street: Street }
#[derive(Get, GetRef, Set, Modify)]
pub struct Street { pub number: u16, pub name: String }
// We create an immutable variable
let john = Employee { // Parent type
name: String::from("john"),
company: Company { // Level 1
name: String::from("awesome inc"),
address: Address { // Level 2
city: String::from("london"),
street: Street { // Level 3
number: 23,
name: String::from("high street"), // Level 4
},
},
},
};
// Using zoom_all! is going to combine the derived Set, Get, GetRef, and Modify of each level
zoom_all![Employee => Company => Address => Street => String];
// Let's change the name of the street, which is at the fourth level
let john_at_low_street = john.set_fourth(String::from("low street"));
// We can retrieve the info by reference
assert_eq!(
"low street",
john_at_low_street.get_ref_fourth().as_str()
);
// With modify, we can apply a function to the target field
let john_at_high_again =
john_at_low_street.modify_fourth(|street_name| street_name.replace("low", "high"));
// We can retrieve the info by value as well
assert_eq!(
"high street",
john_at_high_again.get_fourth().as_str()
);
依赖项
~2MB
~46K SLoC