This crate provides the CmpBy and HashBy derive macros.
- CmpBy derives the traits Ord, PartialOrd, Eq and PartialEq on types that can't automatically derive those traits because they contain unorderable fields such as f32 by selecting fields to use in the comparison.
- CmpBy and HashBy can also implement their traits by calling arbitrary methods
Fields that should be used for sorting are marked with the attribute #[cmp_by].
Other fields will be ignored.
This saves a lot of boilerplate, as you can see with the SomethingElse struct.
```rust use std::cmp::Ordering; use cmpbyderive::CmpBy;
struct Something { #[cmpby] a: u16, #[cmpby] b: u16, c: f32, }
struct SomethingElse { a: u16, b: u16, c: f32, }
impl Eq for SomethingElse {}
impl PartialEq
impl PartialOrd
impl Ord for SomethingElse { fn cmp(&self, other: &Self) -> Ordering { self.a.cmp(&other.a).then_with(|| { self.b.cmp(&other.b) }) } }
asserteq!(Something { a: 2, b: 0, c: 0.2 }.cmp(&Something { a: 1, b: 1, c: 1.3 }), SomethingElse { a: 2, b: 0, c: 0.2 }.cmp(&SomethingElse { a: 1, b: 1, c: 1.3 })); asserteq!(Something { a: 1, b: 0, c: 3.3 }.cmp(&Something { a: 1, b: 1, c: 2.3 }), SomethingElse { a: 1, b: 0, c: 3.3 }.cmp(&SomethingElse { a: 1, b: 1, c: 2.3 })); ```
You can use HashBy the same way you would use CmpBy:
```rust use cmpbyderive::HashBy; use cmpbyderive::CmpBy; use std::collections::hash_set::HashSet;
struct Something { #[cmpby] #[hashby] a: u16, #[cmpby] #[hashby] b: u16, c: f32, }
let mut set = HashSet::new(); let something = Something { a: 2, b: 0, c: 0.2 }; assert!(set.insert(something)); ```