3个版本
0.1.2 | 2018年12月23日 |
---|---|
0.1.1 | 2018年12月21日 |
0.1.0 | 2018年12月21日 |
#55 in #hash-set
在 3 个crate中使用(直接使用2个)
4KB
67 行
SmartHash
Smart Hash 是一系列特质的集合,允许您使用您设计的 HashSet
来进行快速和简单的查询。
这是什么?
smart-hash 添加了一个特质,使其能够轻松地在 HashSet 中进行部分匹配。把它想象成在 HashSet 中查询匹配数据。
限制
- 只能匹配相等(没有lt、gt等...)
最小示例
一个快速“让它工作”的示例,以展示它的工作原理以及如何设置。 (使用新的rust 2018)
extern crate smart_hash;
use smart_hash::{get_matching,SmartHash}; // macros
use smart_hash::traits::SmartHashSet;
#[derive(SmartHash, Hash, Eq, PartialEq)]
pub struct Person {
name : String,
age : u8,
height: u8,
}
pub fn main() {
let people : HashSet<Person> = HashSet::New();
// do something here to add a bunch of people into it....
// not using the macro access method (same result as below)
let people_25 = people.get_matching(PeopleOpt{
name : None,
age : Some(25),
height : None,
});
// using the macro access method (same result as above)
let people_25 = get_matching!(people,age == 25);
// looks at the results
if let Some(people) in people_25 {
for p in people {
// should only print out the people who are 25 (where age == 25)
println!({},p.name);
}
}
}
功能
smart-hash 有一些功能,但默认情况下可能已经满足您的需求。(意思是您不需要做任何事情)
- 默认 - 包括作用域内的所有宏,包括 derive。
- derive - 与默认相同。
- 手动 - 不包括 derive 宏,假设您将自行实现一切。
包含内容?
smart-hash
smart-hash crate 包含以下公共特质。
SmartHashSmartHash 特质使结构体用于部分匹配。它需要一个第二个结构体存在(选项),以及一个函数 into_option
来创建一个 option struct,其中包含原始结构体的值。
假设您的数据结构如下所示。
pub Struct Car {
color : Color,
make : String,
year : Date,
}
为了实现 SmartHash,您需要添加以下内容。
注意:如果您使用 #[derive(SmartHash)]
从 smart-hash-derive,所有这些都将自动为您完成。
// the options struct
pub Struct CarOpt {
color : Option<Color>,
make : Option<String>,
year : Option<Date>,
}
// SmartHash requires Default to be implemented
impl Default for CarOpt {
fn default() -> CarOpt {
CarOpt {
color: None,
make: None,
year:None
}
}
}
// implement SmartHash
impl SmartHash for Car {
type option = CarOpt;
fn into_option(&self) -> CarOpt {
CarOpt {
color: Some(self.color),
make : Some(self.make),
year : Some(self.year),
}
}
}
SmartHashOpt新的选项结构体还需要实现一些空特质...
注意:如果您使用 #[derive(SmartHash)]
从 smart-hash-derive,所有这些都将自动为您完成。
impl SmartHashOpt for CarOpt { }
// allows the partial matching
impl Eq for CarOpt {}
impl PartialEq for CarOpt {
fn eq(&self, other: &CarOpt) -> bool {
(self.color == other.color || self.color.is_none() || other.color.is_none()) &&
(self.make == other.make || self.make.is_none() || other.make.is_none()) &&
(self.year == other.year || self.year.is_none() || other.year.is_none())
}
}
SmartHashSet一个特质,为所有实现 SmartHash 的结构体提供默认实现,这些结构体位于 HashSet 中。这为 HashSet 添加了一个额外的函数,可以执行模糊搜索/部分查询。
// in our example, the signature looks like this
fn get_matching<'a>(&'a self : HashSet<Car>, query : CarOpt) -> Option<Vec<&'a Car>>
get_matching!() 宏还包含一个宏,以便于更轻松、更干净地进行搜索。一旦你使用 #[macro_use]
标记 extern,你就可以使用下面的宏。
// basic signature descriptions
macro get_matching!(object, key, value, k2, v2, ...) -> Option<Vec<object_member>>;
macro get_matching!(object, key == value, k2 == v2, ...) -> Option<Vec<object_member>>;
macro get_matching!(object where key is value, k2 is v2, ...) -> Option<Vec<object_member>>;
derive 宏来自 smart-hash-derive 的 derive 宏在 smart-hash 创建中公开,因此你不需要做任何额外的事情。
smart-hash-derive
包含过程宏的 crate。这里没有其他事情要做,只需 #[macro_use]
extern 并使用宏。如果你使用的是 Rust 2018,则不需要使用此宏,因为它已经包含在基本的 smart-hash crate 中。所有之前的版本都需要使用它来获取 derive 宏。
注意:其他 derive,如 Hash、Eq、PartialEq,是 HashSet 的要求,也是必需的。
#[derive(Hash, Eq, PartialEq, SmartHash)]
pub struct Person {
name : String,
age : u8,
country : String,
}
组织
smart-hash
smart-hash crate 包含了你所需的一切,但使其变得复杂。你将不得不实现很多。你可以查看 测试 来查看需要编写的内容。大部分都是模板和复制粘贴。我建议使用 derive
宏。
smart-hash-derive
smart-hash-derive crate 是一个过程宏,它将自动推导 SmartHash 和其子特质的 derive,这样你就不必担心任何事情。
smart-hash-test
一个独立的二进制应用程序,用于测试宏的作用域并确保一切按计划可访问。
未来
- 允许在宏中使用所有比较运算符:lt、gt、<=、>=、<>等...
依赖关系
~2MB
~46K SLoC