# `ignorable`
[](https://crates.io/crates/ignorable)
[](https://docs.rs/ignorable)


[](https://github.com/nik-rev/ignorable)
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](https://github.com/rust-lang/rfcs/pull/3869)
```toml
[dependencies]
ignorable = "0.1"
```
## Usage
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.
```rust
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 `Hash` and `PartialEq` in sync. We've got that covered!
- This might become a language feature in the future ([RFC 3869](https://github.com/rust-lang/rfcs/pull/3869)),
so you'll be able to transition away from this crate once that time comes!
Remember that it is a [logic error](https://doc.rust-lang.org/stable/std/hash/trait.Hash.html#hash-and-eq)
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.
## With `ignorable`
Uses derives provided by this crate.
```rust
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>
}
```
## Without
You must manually implement each trait.
```rust
#[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 PartialEq for Var {
fn eq(&self, other: &Self) -> bool {
self.ns == other.ns && self.sym == other.sym
}
}
impl Hash for Var {
fn hash<H: Hasher>(&self, state: &mut H) {
(&self.ns, &self.sym).hash(state);
}
}
```
Notes:
- It is logically incorrect for `Hash` and `PartialEq` implementations
to differ, so you must remember to keep them in sync if `Var` changes
- You must remember to update the string names of the `Debug` impl if you
ever rename the fields or `Var` itself