multiversx_sc_modules/
features.rs

1multiversx_sc::imports!();
2
3pub const FEATURE_NOT_SET: u8 = 0;
4pub const FEATURE_ON: u8 = 1;
5pub const FEATURE_OFF: u8 = 2;
6
7/// This is a standard smart contract module, that when added to a smart contract offers feature flag capabilities.
8///
9/// It offers:
10/// * an endpoint where the owner can turn features on/off
11/// * a method to check if feature is on or not
12/// * a macro to make calling this method even more compact
13///
14#[multiversx_sc::module]
15pub trait FeaturesModule {
16    #[storage_mapper("feat:")]
17    fn feature_flag(&self, feature_name: &FeatureName<Self::Api>) -> SingleValueMapper<u8>;
18
19    fn check_feature_on(&self, feature_name: &'static [u8], default: bool) {
20        let flag = self.feature_flag(&FeatureName(feature_name.into())).get();
21        let value = match flag {
22            FEATURE_NOT_SET => default,
23            FEATURE_ON => true,
24            _ => false,
25        };
26        require!(value, "{} currently disabled", feature_name);
27    }
28
29    #[only_owner]
30    #[endpoint(setFeatureFlag)]
31    fn set_feature_flag_endpoint(&self, feature_name: ManagedBuffer, value: bool) {
32        let feature_value = if value { FEATURE_ON } else { FEATURE_OFF };
33        self.feature_flag(&FeatureName(feature_name))
34            .set(feature_value);
35    }
36}
37
38multiversx_sc::derive_imports!();
39
40#[derive(TopEncode)]
41pub struct FeatureName<M>(ManagedBuffer<M>)
42where
43    M: ManagedTypeApi;
44
45use multiversx_sc::codec::*;
46impl<M> NestedEncode for FeatureName<M>
47where
48    M: ManagedTypeApi,
49{
50    #[inline]
51    fn dep_encode_or_handle_err<O, H>(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr>
52    where
53        O: NestedEncodeOutput,
54        H: EncodeErrorHandler,
55    {
56        dest.push_specialized((), &self.0, h)
57    }
58}