1
// Copyright 2024 Moonbeam foundation
2
// This file is part of Moonbeam.
3

            
4
// Moonbeam is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Moonbeam is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Moonbeam.  If not, see <http://www.gnu.org/licenses/>.
16

            
17
/// A trait for querying a value by a key.
18
pub trait GetByKey<Key, Value> {
19
	/// Return the value.
20
	fn get(k: &Key) -> Value;
21
}
22

            
23
/// Create new implementations of the `GetByKey` trait.
24
///
25
/// The implementation is typically used like a map or set.
26
///
27
/// Example:
28
/// ```ignore
29
/// use primitives::CurrencyId;
30
/// parameter_type_with_key! {
31
///     pub Rates: |currency_id: CurrencyId| -> u32 {
32
///         match currency_id {
33
///             CurrencyId::DOT => 1,
34
///             CurrencyId::KSM => 2,
35
///             _ => 3,
36
///         }
37
///     }
38
/// }
39
/// ```
40
#[macro_export]
41
macro_rules! parameter_type_with_key {
42
	(
43
		pub $name:ident: |$k:ident: $key:ty| -> $value:ty $body:block;
44
	) => {
45
		pub struct $name;
46
		impl $crate::get_by_key::GetByKey<$key, $value> for $name {
47
3
			fn get($k: &$key) -> $value {
48
				$body
49
3
			}
50
		}
51
	};
52
}
53

            
54
#[cfg(test)]
55
mod tests {
56
	use super::*;
57

            
58
	parameter_type_with_key! {
59
		pub Test: |k: u32| -> u32 {
60
			match k {
61
				1 => 1,
62
				_ => 2,
63
			}
64
		};
65
	}
66

            
67
	#[test]
68
1
	fn get_by_key_should_work() {
69
1
		assert_eq!(Test::get(&1), 1);
70
1
		assert_eq!(Test::get(&2), 2);
71
1
		assert_eq!(Test::get(&3), 2);
72
1
	}
73
}