#hash #enums #discriminant #traits #fields #variant #derive

macro discriminant_hash_derive

Derive macro to implement Hash trait based on enum's discriminants only and ignore variant's fields

1 unstable release

0.1.0 Jun 11, 2021

#1454 in Procedural macros

MIT/Apache

6KB

discriminant_hash_derive

Deriving DiscriminantHash implements Hash trait for the underlying enum. Here hash is only dependent on discriminant and isn’t effected by variant’s fields.

Example

use discriminant_hash_derive::DiscriminantHash;
use std::{
    collections::hash_map::DefaultHasher,
    hash::{Hash, Hasher},
};

#[derive(DiscriminantHash)]
enum Abc<T> {
    Simple,
    HashNotImplemented(Xyz),
    Generic(T),
}

#[allow(unused)]
#[derive(Hash)]
enum Pqr<'a> {
    Simple,
    Lifetime(&'a str),
}

// Xyz doesn't impl Hash
struct Xyz;

fn main() {
    assert_eq!(my_hash(Abc::Simple::<i32>), my_hash(Abc::Simple::<Xyz>));
    assert_eq!(
        my_hash(Abc::HashNotImplemented::<i32>(Xyz)),
        my_hash(Abc::HashNotImplemented::<String>(Xyz))
    );
    assert_eq!(
        my_hash(Abc::Generic::<i32>(4)),
        my_hash(Abc::Generic::<Xyz>(Xyz))
    );

    assert_ne!(
        my_hash(Abc::Simple::<i32>),
        my_hash(Abc::Generic::<Xyz>(Xyz))
    );

     
    // This may be same depending on how Pqr is defined
    // assert_eq!(
    //     my_hash(Abc::Simple::<i32>),
    //     my_hash(Pqr::Simple)
    // );
     
}

fn my_hash<T>(obj: T) -> u64
where
    T: Hash,
{
    let mut hasher = DefaultHasher::new();
    obj.hash(&mut hasher);
    hasher.finish()
}

Dependencies

~1.5MB
~33K SLoC