partial-cmp-derive
A procedural macro for deriving PartialEq, Eq, PartialOrd, and Ord with fine-grained control over field comparison behavior.
Features
- Consistent trait generation: All four comparison traits are generated with consistent behavior
- Skip fields: Exclude fields from all comparisons (both equality and ordering)
- Custom comparators: Use custom functions for ordering and/or equality
- Sort order control: Ascending or descending per field
- Field priority: Control comparison order independent of declaration order
- Explicit field ordering: Specify exactly which fields to compare and in what order
- Option handling: Control whether
Nonesorts first or last - Enum ranking: Control variant ordering independent of declaration order
- Trait selection: Opt out of specific traits as needed
Installation
[]
= "0.2"
Quick Start
use PartialCmp;
// Generates PartialEq, Eq, PartialOrd, and Ord
let alice = Player ;
let bob = Player ;
// id is ignored, score compared first (desc), then name (asc)
assert!; // Same score, Alice < Bob alphabetically
// Equality also ignores id
let alice2 = Player ;
assert_eq!; // Same score and name, different id - equal!
Attributes
Struct-Level Attributes
| Attribute | Description |
|---|---|
#[ord(reverse)] |
Reverse the final comparison result |
#[ord(by = [field1(asc), field2(desc)])] |
Explicit field comparison order |
#[ord(skip_partial_eq)] |
Don't generate PartialEq (implies no other traits) |
#[ord(skip_eq)] |
Don't generate Eq (also disables Ord) |
#[ord(skip_partial_ord)] |
Don't generate PartialOrd (also disables Ord) |
#[ord(skip_ord)] |
Don't generate Ord |
Field-Level Attributes
| Attribute | Description |
|---|---|
#[ord(skip)] |
Exclude from all comparisons |
#[ord(order = "asc"|"desc")] |
Sort direction (default: asc) |
#[ord(priority = N)] |
Comparison priority (lower = compared first) |
#[ord(compare_with = "path::to::fn")] |
Custom comparison function fn(&T, &T) -> Ordering |
#[ord(eq_with = "path::to::fn")] |
Custom equality function fn(&T, &T) -> bool |
#[ord(none_order = "first"|"last")] |
Where None sorts for Option fields |
Enum Variant Attributes
| Attribute | Description |
|---|---|
#[ord(rank = N)] |
Variant ranking (lower = less than) |
Examples
Skipping Fields
Fields marked with #[ord(skip)] are excluded from both equality and ordering comparisons:
use PartialCmp;
let a = Record ;
let b = Record ;
assert_eq!; // Equal because only value is compared
Explicit Field Ordering
Use by to specify exactly which fields participate in comparison:
use PartialCmp;
Custom Comparison Functions
use PartialCmp;
use Ordering;
let a = AbsValue ;
let b = AbsValue ;
assert_eq!; // Equal because |-5| == |5|
Option Handling
use PartialCmp;
let none = MaybeValue ;
let some = MaybeValue ;
assert!; // None comes first
Enum Ranking
use PartialCmp;
assert!;
assert!;
Working with Non-Ord Types
For types like f32 that don't implement Ord, use skip_ord and skip_eq:
use PartialCmp;
use Ordering;
Trait Dependencies
The trait generation respects the following dependencies:
OrdrequiresEqandPartialOrdEqandPartialOrdrequirePartialEq
When you skip a trait, dependent traits are automatically skipped:
| Skip Flag | Traits Generated |
|---|---|
| (none) | PartialEq, Eq, PartialOrd, Ord |
skip_ord |
PartialEq, Eq, PartialOrd |
skip_eq |
PartialEq, PartialOrd |
skip_partial_ord |
PartialEq, Eq |
skip_eq, skip_ord |
PartialEq, PartialOrd |
skip_partial_eq |
(none) |
License
MIT