This crate provides 5 derives that are just like the standard library's, but they allow to ignore fields when deriving. Inspired by RFC 3869
[dependencies]
ignorable = "0.1"This crate provides 5 derive macros:
- PartialEq
- PartialOrd
- Ord
- Debug
- Hash
The advantage of these derives over the standard library's is that they support
the #[ignored] attribute to ignore individual fields when deriving the respective traits.
use ignorable::{PartialEq, Hash};
// `PartialEq` and `Hash` impls will only check
// the `id` field of 2 `User`s
#[derive(Clone, PartialEq, Eq, Hash)]
struct User {
    #[ignored(PartialEq, Hash)]
    name: String,
    #[ignored(PartialEq, Hash)]
    age: u8,
    id: u64
}Advantages:
- Significantly less boilerplate
- Less maintenance overhead, it's not your responsibility to remember to update manual implementations of traits,
keep traits like HashandPartialEqin sync. We've got that covered!
- This might become a language feature in the future (RFC 3869), so you'll be able to transition away from this crate once that time comes!
Remember that it is a logic error
for the implementations of Hash and PartialEq to differ, and if you need to manually implement the traits
to skip certain fields, you must remember to keep them in sync because you can't use the derive anymore.
Uses derives provided by this crate.
use ignorable::{Debug, PartialEq, Hash};
#[derive(Clone, Debug, PartialEq, Hash)]
pub struct Var<T> {
    pub ns: Symbol,
    pub sym: Symbol,
    #[ignored(PartialEq, Hash)]
    meta: RefCell<protocols::IPersistentMap>,
    #[ignored(PartialEq, Hash)]
    pub root: RefCell<Rc<Value>>,
    #[ignored(Debug)]
    _phantom: PhantomData<T>
}You must manually implement each trait.
#[derive(Clone)]
pub struct Var<T> {
    pub ns: Symbol,
    pub sym: Symbol,
    meta: RefCell<protocols::IPersistentMap>,
    pub root: RefCell<Rc<Value>>,
    _phantom: PhantomData<T>
}
impl<T> fmt::Debug for Var<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Var")
            .field("ns", &self.ns)
            .field("sym", &self.sym)
            .field("meta", &self.meta)
            .field("root", &self.root)
            .finish()
    }
}
impl<T> PartialEq for Var<T> {
    fn eq(&self, other: &Self) -> bool {
        self.ns == other.ns && self.sym == other.sym
    }
}
impl<T> Hash for Var<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        (&self.ns, &self.sym).hash(state);
    }
}Notes:
- It is logically incorrect for HashandPartialEqimplementations to differ, so you must remember to keep them in sync ifVarchanges
- You must remember to update the string names of the Debugimpl if you ever rename the fields orVaritself