derive_more icon indicating copy to clipboard operation
derive_more copied to clipboard

Allow debug() on enums

Open RReverser opened this issue 5 months ago • 3 comments

I have an enum that already has a pub const fn as_str(&self) -> &str function. I want to reuse it for both Display and Debug implementations.

I have no problem doing just that with derive_more::Display, but for some reason the Debug counterpart error out:

#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, derive_more::Debug, derive_more::Display)]
#[display("{}", self.as_str())]
#[debug("{}", self)] // <-- #[debug("...", ...)]` attribute is not allowed on enum, place it on its variants instead
pub enum DeviceType {
  Telescope,
  Camera,
  // ...
}

This seems like an artificial limitation - I assume there's no technical reason for debug() attribute behaving differently than display()?

RReverser avatar Aug 16 '25 19:08 RReverser

@RReverser derive(Debug) and derive(Display) work totally different:

  • derive(Display) is about composing the string representation of the type.
  • derive(Debug) works similarly to the one from std (just has more batteries included), by exposing the structurality of the implementer type.

Those are semantically two different macros with different expansion logic.

At the moment, derive(Debug) doesn't support the enum-level attribute allowing to overwrite the structural implementation, only struct/variant-level ones.

It could be added, of course. However, the semantics may vary, and it could be expected to act differently: some people would like to act it in an overwriting manner, others will expect it to provide the "default" representation for variants.

tyranron avatar Dec 01 '25 20:12 tyranron

Hm I don't really see it as any different - they're just 2 traits in the large family of std::fmt traits, just like UpperHex, Binary, Pointer etc etc.

I think it would be very confusing for the same attribute to work differently for these two derives, just like I was already confused why same attribute might not work on one of the derives.

If someone wants a "default for any variant", I believe it should be added as a separate attribute instead of repurposing existing one with different semantics.

RReverser avatar Dec 01 '25 20:12 RReverser

@RReverser

Hm I don't really see it as any different - they're just 2 traits in the large family of std::fmt traits, just like UpperHex, Binary, Pointer etc etc.

Yet, they are. At least their deriving logic.

If someone wants a "default for any variant", I believe it should be added as a separate attribute instead of repurposing existing one with different semantics.

Theoretically, we could do this the same way as in Display-like derives (there is some auto-detection whether to used "defaulting" logic, checkout docs for more), but I need to think more on possible implications.

tyranron avatar Dec 01 '25 20:12 tyranron