Skip to content

Instantly share code, notes, and snippets.

@jplatte
Created April 18, 2025 10:53
Show Gist options
  • Save jplatte/505fadf71e962829838f0a5eceb44b59 to your computer and use it in GitHub Desktop.
Save jplatte/505fadf71e962829838f0a5eceb44b59 to your computer and use it in GitHub Desktop.
Rust conditional derive trick
// make sure to put the attributes thing there, so
// #[serde()] attributes are allowed for the dummy macros
#[proc_macro_derive(Deserialize, attributes(serde))]
pub fn dummy_deserialize(_input: TokenStream) -> TokenStream {
TokenStream::new()
}
// could maybe just export the same macro twice under the same name,
// here or in the re-export module, as an alternative
#[proc_macro_derive(Serialize, attributes(serde))]
pub fn dummy_deserialize(_input: TokenStream) -> TokenStream {
TokenStream::new()
}
mod _hack {
pub use serde::*;
// shadow serde's macros (but not the traits) conditionally
#[cfg(not(feature = "serde")]
pub use dummy_macro::{Deserialize, Serialize};
}
pub use _hack::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
#[serde(whatever)]
struct Foo {
#[serde(rename = "type")]
type_: FooType,
#[serde(default = "default_fn")]
bar: i64,
}
// because the dummy macro doesn't use default_fn,
// have to cfg it to avoid dead_code warnings
#[cfg(feature = "serde")]
fn default_fn() -> i64 { 5 }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment