#![cfg_attr(not(feature = "std"), no_std)]
#![deny(missing_docs)]
#![allow(rustdoc::broken_intra_doc_links)]
#![doc = docify::embed!("src/tests/mock.rs", dynamic_params)]
#![doc = docify::embed!("src/tests/mock.rs", custom_origin)]
#![doc = docify::embed!("src/tests/mock.rs", benchmarking_default)]
#![doc = docify::embed!("src/tests/mock.rs", impl_config)]
#![doc = docify::embed!("src/tests/mock.rs", usage)]
#![doc = docify::embed!("src/tests/unit.rs", set_parameters_example)]
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
use frame_support::traits::{
dynamic_params::{AggregatedKeyValue, IntoKey, Key, RuntimeParameterStore, TryIntoKey},
EnsureOriginWithArg,
};
mod benchmarking;
#[cfg(test)]
mod tests;
mod weights;
pub use pallet::*;
pub use weights::WeightInfo;
type KeyOf<T> = <<T as Config>::RuntimeParameters as AggregatedKeyValue>::Key;
type ValueOf<T> = <<T as Config>::RuntimeParameters as AggregatedKeyValue>::Value;
#[frame_support::pallet]
pub mod pallet {
use super::*;
#[pallet::config(with_default)]
pub trait Config: frame_system::Config {
#[pallet::no_default_bounds]
#[allow(deprecated)]
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
#[pallet::no_default_bounds]
type RuntimeParameters: AggregatedKeyValue;
#[pallet::no_default_bounds]
type AdminOrigin: EnsureOriginWithArg<Self::RuntimeOrigin, KeyOf<Self>>;
type WeightInfo: WeightInfo;
}
#[pallet::event]
#[pallet::generate_deposit(pub(crate) fn deposit_event)]
pub enum Event<T: Config> {
Updated {
key: <T::RuntimeParameters as AggregatedKeyValue>::Key,
old_value: Option<<T::RuntimeParameters as AggregatedKeyValue>::Value>,
new_value: Option<<T::RuntimeParameters as AggregatedKeyValue>::Value>,
},
}
#[pallet::storage]
pub type Parameters<T: Config> =
StorageMap<_, Blake2_128Concat, KeyOf<T>, ValueOf<T>, OptionQuery>;
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight(T::WeightInfo::set_parameter())]
pub fn set_parameter(
origin: OriginFor<T>,
key_value: T::RuntimeParameters,
) -> DispatchResult {
let (key, new) = key_value.into_parts();
T::AdminOrigin::ensure_origin(origin, &key)?;
let mut old = None;
Parameters::<T>::mutate(&key, |v| {
old = v.clone();
*v = new.clone();
});
Self::deposit_event(Event::Updated { key, old_value: old, new_value: new });
Ok(())
}
}
pub mod config_preludes {
use super::*;
use frame_support::derive_impl;
pub struct TestDefaultConfig;
#[derive_impl(frame_system::config_preludes::TestDefaultConfig, no_aggregated_types)]
impl frame_system::DefaultConfig for TestDefaultConfig {}
#[frame_support::register_default_impl(TestDefaultConfig)]
impl DefaultConfig for TestDefaultConfig {
#[inject_runtime_type]
type RuntimeEvent = ();
#[inject_runtime_type]
type RuntimeParameters = ();
type AdminOrigin = frame_support::traits::AsEnsureOriginWithArg<
frame_system::EnsureRoot<Self::AccountId>,
>;
type WeightInfo = ();
}
}
}
impl<T: Config> RuntimeParameterStore for Pallet<T> {
type AggregatedKeyValue = T::RuntimeParameters;
fn get<KV, K>(key: K) -> Option<K::Value>
where
KV: AggregatedKeyValue,
K: Key + Into<<KV as AggregatedKeyValue>::Key>,
<KV as AggregatedKeyValue>::Key: IntoKey<
<<Self as RuntimeParameterStore>::AggregatedKeyValue as AggregatedKeyValue>::Key,
>,
<<Self as RuntimeParameterStore>::AggregatedKeyValue as AggregatedKeyValue>::Value:
TryIntoKey<<KV as AggregatedKeyValue>::Value>,
<KV as AggregatedKeyValue>::Value: TryInto<K::WrappedValue>,
{
let key: <KV as AggregatedKeyValue>::Key = key.into();
let val = Parameters::<T>::get(key.into_key());
val.and_then(|v| {
let val: <KV as AggregatedKeyValue>::Value = v.try_into_key().ok()?;
let val: K::WrappedValue = val.try_into().ok()?;
let val = val.into();
Some(val)
})
}
}