use alloc::vec::Vec;
use sp_runtime::BoundedVec;
pub const MAX_BUDGET_KEY_LEN: u32 = 32;
pub type BudgetKey = BoundedVec<u8, sp_core::ConstU32<MAX_BUDGET_KEY_LEN>>;
pub trait IssuanceCurve<Balance> {
fn issue(total_issuance: Balance, elapsed_millis: u64) -> Balance;
}
impl<Balance: Default> IssuanceCurve<Balance> for () {
fn issue(_total_issuance: Balance, _elapsed_millis: u64) -> Balance {
Default::default()
}
}
pub trait BudgetRecipient<AccountId> {
fn budget_key() -> BudgetKey;
fn pot_account() -> AccountId;
}
pub trait BudgetRecipientList<AccountId> {
fn recipients() -> Vec<(BudgetKey, AccountId)>;
}
impl<AccountId> BudgetRecipientList<AccountId> for () {
fn recipients() -> Vec<(BudgetKey, AccountId)> {
Vec::new()
}
}
#[impl_trait_for_tuples::impl_for_tuples(1, 10)]
#[tuple_types_custom_trait_bound(BudgetRecipient<AccountId>)]
impl<AccountId> BudgetRecipientList<AccountId> for Tuple {
fn recipients() -> Vec<(BudgetKey, AccountId)> {
let mut v = Vec::new();
for_tuples!( #( v.push((Tuple::budget_key(), Tuple::pot_account())); )* );
debug_assert!(
{
let mut keys: Vec<_> = v.iter().map(|(k, _)| k.clone()).collect();
keys.sort();
keys.windows(2).all(|w| w[0] != w[1])
},
"Duplicate BudgetRecipient key detected"
);
v
}
}
#[cfg(test)]
mod tests {
use super::*;
struct RecipientA;
impl BudgetRecipient<u64> for RecipientA {
fn budget_key() -> BudgetKey {
BudgetKey::truncate_from(b"alpha".to_vec())
}
fn pot_account() -> u64 {
1
}
}
struct RecipientB;
impl BudgetRecipient<u64> for RecipientB {
fn budget_key() -> BudgetKey {
BudgetKey::truncate_from(b"beta".to_vec())
}
fn pot_account() -> u64 {
2
}
}
struct RecipientDuplicate;
impl BudgetRecipient<u64> for RecipientDuplicate {
fn budget_key() -> BudgetKey {
BudgetKey::truncate_from(b"alpha".to_vec())
}
fn pot_account() -> u64 {
3
}
}
#[test]
fn unique_keys_work() {
let recipients = <(RecipientA, RecipientB) as BudgetRecipientList<u64>>::recipients();
assert_eq!(recipients.len(), 2);
}
#[test]
#[should_panic(expected = "Duplicate BudgetRecipient key detected")]
fn duplicate_keys_panics() {
let _ = <(RecipientA, RecipientDuplicate) as BudgetRecipientList<u64>>::recipients();
}
}