From d02c0222bc0109d0ad611a9d9f78d684b33a32fc Mon Sep 17 00:00:00 2001 From: Gavin Wood <gavin@parity.io> Date: Tue, 27 Apr 2021 14:33:59 +0200 Subject: [PATCH] Introduce macro for building Contains impl based on a match (#8675) * Introduce macro for building Contains impl based on a match * Fixes --- substrate/frame/support/src/traits/members.rs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/substrate/frame/support/src/traits/members.rs b/substrate/frame/support/src/traits/members.rs index 35748ca9c0c..125f096fa92 100644 --- a/substrate/frame/support/src/traits/members.rs +++ b/substrate/frame/support/src/traits/members.rs @@ -31,6 +31,36 @@ impl<T: Ord> Contains<T> for All<T> { fn contains(_: &T) -> bool { true } } +/// Create a type which implements the `Contains` trait for a particular type with syntax similar +/// to `matches!`. +#[macro_export] +macro_rules! match_type { + ( pub type $n:ident: impl Contains<$t:ty> = { $phead:pat $( | $ptail:pat )* } ; ) => { + pub struct $n; + impl $crate::traits::Contains<$t> for $n { + fn contains(l: &$t) -> bool { + matches!(l, $phead $( | $ptail )* ) + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + match_type! { + pub type OneOrTenToTwenty: impl Contains<u8> = { 1 | 10..=20 }; + } + + #[test] + fn match_type_works() { + for i in 0..=255 { + assert_eq!(OneOrTenToTwenty::contains(&i), i == 1 || i >= 10 && i <= 20); + } + } +} + /// A trait for a set which can enumerate its members in order. pub trait SortedMembers<T: Ord> { /// Get a vector of all members in the set, ordered. -- GitLab