andromeda_std/ado_base/
modules.rs

1use crate::amp::addresses::AndrAddr;
2#[cfg(feature = "modules")]
3use crate::error::ContractError;
4
5use cosmwasm_schema::cw_serde;
6#[cfg(feature = "modules")]
7use cosmwasm_std::ensure;
8
9/// A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated
10#[cw_serde]
11pub struct Module {
12    pub name: Option<String>,
13    pub address: AndrAddr,
14    pub is_mutable: bool,
15}
16
17#[cfg(feature = "modules")]
18impl Module {
19    pub fn new(name: impl Into<String>, address: impl Into<String>, is_mutable: bool) -> Module {
20        Module {
21            name: Some(name.into()),
22            address: AndrAddr::from_string(address.into()),
23            is_mutable,
24        }
25    }
26
27    /// Validates `self` by checking that it is unique, does not conflict with any other module,
28    /// and does not conflict with the creating ADO.
29    pub fn validate(&self, modules: &[Module]) -> Result<(), ContractError> {
30        ensure!(self.is_unique(modules), ContractError::ModuleNotUnique {});
31
32        Ok(())
33    }
34
35    /// Determines if `self` is unique within the context of a vector of `Module`
36    ///
37    /// ## Arguments
38    /// * `all_modules` - The vector of modules containing the provided module
39    ///
40    /// Returns a `boolean` representing whether the module is unique or not
41    fn is_unique(&self, all_modules: &[Module]) -> bool {
42        let mut total = 0;
43        all_modules.iter().for_each(|m| {
44            if self.name == m.name {
45                total += 1;
46            }
47        });
48
49        total == 1
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    #[cfg(feature = "modules")]
56    use super::*;
57
58    #[test]
59    #[cfg(feature = "modules")]
60    fn test_validate_uniqueness() {
61        let module1 = Module::new("module", "addr1", false);
62        let module2 = Module::new("module", "addr2", false);
63
64        let res = module1.validate(&[module1.clone(), module2]);
65        assert_eq!(ContractError::ModuleNotUnique {}, res.unwrap_err());
66    }
67}