numbat_wasm_module_features/
lib.rs

1#![no_std]
2
3numbat_wasm::imports!();
4
5pub const FEATURE_NOT_SET: u8 = 0;
6pub const FEATURE_ON: u8 = 1;
7pub const FEATURE_OFF: u8 = 2;
8
9/// Standard module for managing feature flags.
10#[numbat_wasm::module]
11pub trait FeaturesModule {
12    #[storage_get("feat:")]
13    fn get_feature_flag(&self, feature_name: FeatureName) -> u8;
14
15    #[storage_set("feat:")]
16    fn set_feature_flag(&self, feature_name: FeatureName, value: u8);
17
18    fn check_feature_on(&self, feature_name: &'static [u8], default: bool) {
19        let flag = self.get_feature_flag(FeatureName(feature_name));
20        let value = match flag {
21            FEATURE_NOT_SET => default,
22            FEATURE_ON => true,
23            _ => false,
24        };
25        if !value {
26            let mut err = self.error().new_error();
27            err.append_bytes(feature_name);
28            err.append_bytes(&b" currently disabled"[..]);
29            err.exit_now()
30        }
31    }
32
33    #[endpoint(setFeatureFlag)]
34    fn set_feature_flag_endpoint(&self, feature_name: Vec<u8>, value: bool) -> SCResult<()> {
35        require!(
36            self.blockchain().get_caller() == self.blockchain().get_owner_address(),
37            "only owner allowed to change features"
38        );
39
40        self.set_feature_flag(
41            FeatureName(feature_name.as_slice()),
42            if value { FEATURE_ON } else { FEATURE_OFF },
43        );
44        Ok(())
45    }
46}
47
48numbat_wasm::derive_imports!();
49
50#[derive(TopEncode)]
51pub struct FeatureName<'a>(&'a [u8]);
52
53use numbat_wasm::numbat_codec::*;
54impl<'a> NestedEncode for FeatureName<'a> {
55    #[inline]
56    fn dep_encode<O: NestedEncodeOutput>(&self, dest: &mut O) -> Result<(), EncodeError> {
57        dest.write(self.0);
58        Result::Ok(())
59    }
60
61    #[inline]
62    fn dep_encode_or_exit<O: NestedEncodeOutput, ExitCtx: Clone>(
63        &self,
64        dest: &mut O,
65        _: ExitCtx,
66        _: fn(ExitCtx, EncodeError) -> !,
67    ) {
68        dest.write(self.0);
69    }
70}