3个版本
0.1.2 | 2018年12月23日 |
---|---|
0.1.1 | 2018年12月21日 |
0.1.0 | 2018年12月21日 |
#49 在 #hash-set
在 2 crate中使用
5KB
61 行
SmartHash
Smart Hash 是一系列特性集合,允许您使用您设计的 struct 的 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 create 中暴露,因此您无需进行任何额外操作。
smart-hash-derive
包含过程宏的箱子。这里除了使用#[macro_use]
声明外部宏并使用宏之外,没有其他事情要做。如果您使用Rust 2018,则无需使用此功能,因为它已包含在基础smart-hash箱子中。所有之前的版本都需要使用它来获取派生宏。
注意:其他派生,如Hash、Eq、PartialEq是HashSet的要求,也是必需的。
#[derive(Hash, Eq, PartialEq, SmartHash)]
pub struct Person {
name : String,
age : u8,
country : String,
}
组织
smart-hash
smart-hash箱子包含了您需要的所有东西,但使其变得复杂。您将不得不实现很多。您可以查看测试以了解需要编写什么。大部分是样板代码和复制粘贴。我建议使用derive
宏。
smart-hash-derive
smart-hash-derive箱子是一个过程宏,可以自动派生SmartHash及其子特性行为,因此您无需担心任何问题。
smart-hash-test
一个独立的二进制应用程序,用于测试宏的作用域并确保一切按计划可访问。
未来
- 允许宏中使用所有比较运算符:lt、gt、<=、>=、<>等...
依赖项
~2MB
~46K SLoC