From 0fff0d28db4a2f207c1c825e50c746bcdc7d9ee4 Mon Sep 17 00:00:00 2001
From: Caio <c410.f3r@gmail.com>
Date: Fri, 6 Sep 2019 16:31:37 -0300
Subject: [PATCH] Implement `Maybe*` marker traits using a declarative macro
 (#3557)

Although simple, the current `Maybe*` trait implementations are based on
a manual approach that uses some code duplication. Now this duplication
is removed using a declarative macro.
Tested locally, the modification don't seem to affect building times.
---
 substrate/core/sr-primitives/src/traits.rs | 96 +++++++---------------
 1 file changed, 31 insertions(+), 65 deletions(-)

diff --git a/substrate/core/sr-primitives/src/traits.rs b/substrate/core/sr-primitives/src/traits.rs
index 0ac40e99424..bbcb46be3d5 100644
--- a/substrate/core/sr-primitives/src/traits.rs
+++ b/substrate/core/sr-primitives/src/traits.rs
@@ -590,77 +590,43 @@ impl<H: PartialEq + Eq + MaybeDebug> CheckEqual for super::generic::DigestItem<H
 	}
 }
 
-/// A type that implements Serialize and Debug when in std environment.
-#[cfg(feature = "std")]
-pub trait MaybeSerializeDebugButNotDeserialize: Serialize + Debug {}
-#[cfg(feature = "std")]
-impl<T: Serialize + Debug> MaybeSerializeDebugButNotDeserialize for T {}
-
-/// A type that implements Serialize and Debug when in std environment.
-#[cfg(not(feature = "std"))]
-pub trait MaybeSerializeDebugButNotDeserialize {}
-#[cfg(not(feature = "std"))]
-impl<T> MaybeSerializeDebugButNotDeserialize for T {}
-
-/// A type that implements Serialize when in std environment.
-#[cfg(feature = "std")]
-pub trait MaybeSerialize: Serialize {}
-#[cfg(feature = "std")]
-impl<T: Serialize> MaybeSerialize for T {}
-
-/// A type that implements Serialize when in std environment.
-#[cfg(not(feature = "std"))]
-pub trait MaybeSerialize {}
-#[cfg(not(feature = "std"))]
-impl<T> MaybeSerialize for T {}
-
-/// A type that implements Serialize, DeserializeOwned and Debug when in std environment.
-#[cfg(feature = "std")]
-pub trait MaybeSerializeDebug: Serialize + DeserializeOwned + Debug {}
-#[cfg(feature = "std")]
-impl<T: Serialize + DeserializeOwned + Debug> MaybeSerializeDebug for T {}
+macro_rules! impl_maybe_marker {
+	( $( $(#[$doc:meta])+ $trait_name:ident: $($trait_bound:path),+ );+ ) => {
+		$(
+			$(#[$doc])+
+			#[cfg(feature = "std")]
+			pub trait $trait_name: $($trait_bound +)+ {}
+			#[cfg(feature = "std")]
+			impl<T: $($trait_bound +)+> $trait_name for T {}
+
+			$(#[$doc])+
+			#[cfg(not(feature = "std"))]
+			pub trait $trait_name {}
+			#[cfg(not(feature = "std"))]
+			impl<T> $trait_name for T {}
+		)+
+	}
+}
 
-/// A type that implements Serialize, DeserializeOwned and Debug when in std environment.
-#[cfg(not(feature = "std"))]
-pub trait MaybeSerializeDebug {}
-#[cfg(not(feature = "std"))]
-impl<T> MaybeSerializeDebug for T {}
+impl_maybe_marker!(
+	/// A type that implements Debug when in std environment.
+	MaybeDebug: Debug;
 
-/// A type that implements Debug when in std environment.
-#[cfg(feature = "std")]
-pub trait MaybeDebug: Debug {}
-#[cfg(feature = "std")]
-impl<T: Debug> MaybeDebug for T {}
+	/// A type that implements Display when in std environment.
+	MaybeDisplay: Display;
 
-/// A type that implements Debug when in std environment.
-#[cfg(not(feature = "std"))]
-pub trait MaybeDebug {}
-#[cfg(not(feature = "std"))]
-impl<T> MaybeDebug for T {}
+	/// A type that implements Hash when in std environment.
+	MaybeHash: ::rstd::hash::Hash;
 
-/// A type that implements Display when in std environment.
-#[cfg(feature = "std")]
-pub trait MaybeDisplay: Display {}
-#[cfg(feature = "std")]
-impl<T: Display> MaybeDisplay for T {}
-
-/// A type that implements Display when in std environment.
-#[cfg(not(feature = "std"))]
-pub trait MaybeDisplay {}
-#[cfg(not(feature = "std"))]
-impl<T> MaybeDisplay for T {}
+	/// A type that implements Serialize when in std environment.
+	MaybeSerialize: Serialize;
 
-/// A type that implements Hash when in std environment.
-#[cfg(feature = "std")]
-pub trait MaybeHash: ::rstd::hash::Hash {}
-#[cfg(feature = "std")]
-impl<T: ::rstd::hash::Hash> MaybeHash for T {}
+	/// A type that implements Serialize, DeserializeOwned and Debug when in std environment.
+	MaybeSerializeDebug: Debug, DeserializeOwned, Serialize;
 
-/// A type that implements Hash when in std environment.
-#[cfg(not(feature = "std"))]
-pub trait MaybeHash {}
-#[cfg(not(feature = "std"))]
-impl<T> MaybeHash for T {}
+	/// A type that implements Serialize and Debug when in std environment.
+	MaybeSerializeDebugButNotDeserialize: Debug, Serialize
+);
 
 /// A type that provides a randomness beacon.
 pub trait RandomnessBeacon {
-- 
GitLab