Crate partial_cmp_derive

Crate partial_cmp_derive 

Source
Expand description

§partial-cmp-derive

A procedural macro crate for deriving PartialEq, Eq, PartialOrd, Ord, and Hash with fine-grained control over field comparison and hashing behavior.

§Features

  • Skip fields: Use #[ord(skip)] to exclude fields from all comparisons and hashing. Skipped fields are ignored in equality, ordering, and hash computations.
  • Sort order: Use #[ord(order = "asc")] or #[ord(order = "desc")] per field
  • Explicit ordering: Use #[ord(by = [field1(desc), field2(asc)])] at struct level
  • Field priority: Use #[ord(priority = N)] for implicit ordering (lower = first)
  • Key extraction: Use #[ord(key = "path::to::fn")] to extract a comparable key
  • Reverse all: Use #[ord(reverse)] at struct level to reverse entire comparison
  • Enum ranking: Use #[ord(rank = N)] to control variant ordering
  • Option handling: Use #[ord(none_order = "first")] or "last"
  • Trait selection: Control which traits are generated with skip flags

§Trait Generation

By default, all five traits are generated: PartialEq, Eq, PartialOrd, Ord, and Hash. The Hash implementation is consistent with Eq, ensuring the invariant a == b -> hash(a) == hash(b) holds. You can opt out of specific traits:

  • #[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
  • #[ord(skip_hash)] — Don’t generate Hash

§Example

use partial_cmp_derive::PartialCmp;

// Generates PartialEq, Eq, PartialOrd, Ord, and Hash
#[derive(PartialCmp)]
struct Point {
    x: i32,
    y: i32,
}

// Skipped fields are excluded from all comparisons and hashing
// Use skip_eq, skip_ord, and skip_hash when non-skipped fields don't implement those traits
#[derive(Debug, PartialCmp)]
#[ord(skip_eq, skip_ord, skip_hash)]
struct Measurement {
    #[ord(skip)]
    raw_value: f32,  // Ignored in eq, cmp, and hash
    timestamp: u64,
}

// Compare by absolute value using a key function
#[derive(Debug, PartialCmp)]
struct AbsValue {
    #[ord(key = "abs_key")]
    value: i32,
}

fn abs_key(v: &i32) -> i32 {
    v.abs()
}

This generates consistent implementations where skipped fields are ignored in equality, ordering, and hash computations.

§Key Extraction

The key attribute allows you to specify a function that extracts a comparable value from a field. This single function is used for Eq, Ord, and Hash, ensuring consistency across all three traits automatically:

use partial_cmp_derive::PartialCmp;

fn abs_key(v: &i32) -> i32 {
    v.abs()
}

#[derive(Debug, PartialCmp)]
struct AbsValue {
    #[ord(key = "abs_key")]
    value: i32,
}

let a = AbsValue { value: -5 };
let b = AbsValue { value: 5 };

// Both are equal because abs(-5) == abs(5)
assert_eq!(a, b);
// And their hashes are equal too (Hash/Eq invariant maintained)

The key function signature should be fn(&T) -> U where U: Ord + Hash.

Derive Macros§

PartialCmp
Derives comparison and hash traits with customizable field behavior.