88

I have added a feature in my crate which adds serde support. However, I don't quite understand how to use it properly:

// #[derive(Debug, Serialize, Deserialize, Clone)] // goes to:

#[derive(Debug, Clone)]
#[cfg(feature = "serde_support")]
#[derive(Serialize, Deserialize)]
pub struct MyStruct;

This code treats everything below cfg(feature) as conditionally compiled, so without my serde_support feature my crate does not have MyStruct also.

I have tried to wrap it with braces but it gives another error:

Code:

#[derive(Debug, Clone)]
#[cfg(feature = "serde_support")] {
#[derive(Serialize, Deserialize)]
}
pub struct MyStruct;

Error:

error: expected item after attributes
  --> mycrate/src/lib.rs:65:33
   |
65 | #[cfg(feature = "serde_support")] {
   |                                 ^

So how to do this?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
VP.
  • 15,509
  • 17
  • 91
  • 161

1 Answers1

142

You can use the cfg_attr(a, b) attribute:

#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
pub struct MyStruct;

It's described in the Rust reference about "conditional compilation":

#[cfg_attr(a, b)]
item

Will be the same as #[b] item if a is set by cfg, and item otherwise.

Sanpi
  • 420
  • 7
  • 18
Lukas Kalbertodt
  • 79,749
  • 26
  • 255
  • 305
  • 2
    But how do you get the docs to say that `MyStruct` only implements `Serialize` and `Deserialize` if the `serde_support` feature is enabled? – RBF06 Dec 16 '22 at 22:48
  • @RBF06 I'm guessing by now you probably already got a way to do this. If not might be better as a separate question. – One Jul 01 '23 at 01:54