iota_types/
config.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use move_core_types::{
6    account_address::AccountAddress,
7    ident_str,
8    identifier::IdentStr,
9    language_storage::{StructTag, TypeTag},
10};
11use serde::{Deserialize, Serialize};
12
13use crate::{IOTA_FRAMEWORK_ADDRESS, MoveTypeTagTrait, base_types::EpochId, id::UID};
14
15pub const CONFIG_MODULE_NAME: &IdentStr = ident_str!("config");
16pub const CONFIG_STRUCT_NAME: &IdentStr = ident_str!("Config");
17pub const SETTING_STRUCT_NAME: &IdentStr = ident_str!("Setting");
18pub const SETTING_DATA_STRUCT_NAME: &IdentStr = ident_str!("SettingData");
19pub const RESOLVED_IOTA_CONFIG: (&AccountAddress, &IdentStr, &IdentStr) = (
20    &IOTA_FRAMEWORK_ADDRESS,
21    CONFIG_MODULE_NAME,
22    CONFIG_STRUCT_NAME,
23);
24
25/// Rust representation of the Move type 0x2::config::Config.
26#[derive(Debug, Serialize, Deserialize)]
27pub struct Config {
28    pub id: UID,
29}
30
31/// Rust representation of the Move type 0x2::config::Setting.
32#[derive(Debug, Serialize, Deserialize)]
33pub struct Setting<V> {
34    pub data: Option<SettingData<V>>,
35}
36
37/// Rust representation of the Move type 0x2::config::SettingData.
38#[derive(Debug, Serialize, Deserialize)]
39pub struct SettingData<V> {
40    pub newer_value_epoch: u64,
41    pub newer_value: Option<V>,
42    pub older_value_opt: Option<V>,
43}
44
45impl Config {
46    pub fn type_() -> StructTag {
47        StructTag {
48            address: IOTA_FRAMEWORK_ADDRESS,
49            module: CONFIG_MODULE_NAME.to_owned(),
50            name: CONFIG_STRUCT_NAME.to_owned(),
51            type_params: vec![],
52        }
53    }
54}
55
56pub fn setting_type(value_tag: TypeTag) -> StructTag {
57    StructTag {
58        address: IOTA_FRAMEWORK_ADDRESS,
59        module: CONFIG_MODULE_NAME.to_owned(),
60        name: SETTING_STRUCT_NAME.to_owned(),
61        type_params: vec![value_tag],
62    }
63}
64
65impl MoveTypeTagTrait for Config {
66    fn get_type_tag() -> TypeTag {
67        TypeTag::Struct(Box::new(Config::type_()))
68    }
69}
70
71impl<V: MoveTypeTagTrait> MoveTypeTagTrait for Setting<V> {
72    fn get_type_tag() -> TypeTag {
73        TypeTag::Struct(Box::new(setting_type(V::get_type_tag())))
74    }
75}
76
77pub fn is_setting(tag: &StructTag) -> bool {
78    let StructTag {
79        address,
80        module,
81        name,
82        type_params,
83    } = tag;
84    *address == IOTA_FRAMEWORK_ADDRESS
85        && module.as_ident_str() == CONFIG_MODULE_NAME
86        && name.as_ident_str() == SETTING_STRUCT_NAME
87        && type_params.len() == 1
88}
89
90impl<V> Setting<V> {
91    /// Calls `SettingData::read_value` on the setting's data.
92    /// The `data` should never be `None`, but for safety, this method returns
93    /// `None` if it is.
94    pub fn read_value(&self, cur_epoch: Option<EpochId>) -> Option<&V> {
95        self.data.as_ref()?.read_value(cur_epoch)
96    }
97}
98
99impl<V> SettingData<V> {
100    /// Reads the value of the setting, giving `newer_value` if the current
101    /// epoch is greater than `newer_value_epoch`, and `older_value_opt`
102    /// otherwise. If `cur_epoch` is `None`, the `newer_value` is always
103    /// returned.
104    pub fn read_value(&self, cur_epoch: Option<EpochId>) -> Option<&V> {
105        let use_newer_value = match cur_epoch {
106            Some(cur_epoch) => cur_epoch > self.newer_value_epoch,
107            None => true,
108        };
109        if use_newer_value {
110            self.newer_value.as_ref()
111        } else {
112            self.older_value_opt.as_ref()
113        }
114    }
115}