How to flag fields to be ignored when using derive

I recently was required to add both a vec of functions and a HashMap of struct->function to an existing struct. The problem is, that struct has #[derive(Serialize, Deserialize, Debug, Clone)]. That's all fine when the struct contained primitive data types, but one cannot (at least usefully) print a HashMap<Foo,FnOnce>. It's also a problem for serialization, etc.

So, how can I flag these fields as ignored for these macros? Or, simply isolate them?

Here's a snip of the code in question:

type BlockchainResult = Result<(), Box<dyn Error>>;
type OnTransactionSettled<'lt> = Box<dyn FnOnce(&Transaction) -> BlockchainResult + 'lt>;
type OnBlockEvent<'lt> = Box<dyn FnOnce(&Block) -> BlockchainResult + 'lt>;

#[derive(Serialize, Deserialize, Debug)]
pub struct Blockchain <'lt> {
    trans_observers: HashMap<&'lt Transaction, OnTransactionSettled<'lt>>,
    block_observers: Vec<OnBlockEvent<'lt>>,
    pub genesis_block: GenesisBlock,
    pub blocks: Vec<Block>,
}

Sample error:

125 | #[derive(Serialize, Deserialize, Debug)]
    |                                  ----- in this derive macro expansion
...
130 |     block_observers: Vec<OnBlockEvent<'lt>>,
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn for<'r> FnOnce(&'r block::Block) -> Result<(), Box<(dyn StdError + 'static)>>` cannot be formatted using `{:?}` because it doesn't implement `Debug`

The standard library's custom derives don't provide any attributes to skip a field, so you will either need to write the Debug implementation yourself or use a different derive macro.

Normally I'll just implement Debug manually, using pattern matching to make sure I get a compile error if I add/remove a field which might mess up that Debug impl.

impl<'lt> Debug for Blockchain<'lt> {
  fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    let Blockchain { trans_observers, genesis_block, blocks, block_observers: _ } = self;

    f.debug_struct("Blockchain")
      .field("trans_observers", trans_observers)
      .field("genesis_block", genesis_block)
      .field("blocks", blocks)
      .finish()
  }
}
3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.