#hash-set #search #query #database #macro-derive

smart-hash

在HashSet中进行部分查询,特性

3个版本

0.1.2 2018年12月23日
0.1.1 2018年12月21日
0.1.0 2018年12月21日

#49#hash-set


2 crate中使用

MIT 协议

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 包含以下公共特性。

SmartHash

SmartHash 特性使得结构体可以用于部分匹配。它需要一个第二结构体(选项)和一个 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箱子中。所有之前的版本都需要使用它来获取派生宏。

注意:其他派生,如HashEqPartialEq是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