abstract_os/objects/
module_reference.rs

1use crate::{error::AbstractOsError, AbstractResult};
2use cosmwasm_std::{Addr, Deps};
3
4#[cosmwasm_schema::cw_serde]
5#[non_exhaustive]
6pub enum ModuleReference {
7    /// Core Abstract Contracts
8    Core(u64),
9    /// Native Abstract Contracts
10    Native(Addr),
11    /// Installable apis
12    Api(Addr),
13    /// Installable apps
14    App(u64),
15    /// A stand-alone contract
16    Standalone(u64),
17}
18
19impl ModuleReference {
20    /// Validates that addresses are valid
21    pub fn validate(&self, deps: Deps) -> AbstractResult<()> {
22        match self {
23            ModuleReference::Native(addr) => {
24                deps.api.addr_validate(addr.as_str())?;
25            }
26            ModuleReference::Api(addr) => {
27                deps.api.addr_validate(addr.as_str())?;
28            }
29            _ => (),
30        };
31        Ok(())
32    }
33
34    pub fn unwrap_core(&self) -> AbstractResult<u64> {
35        match self {
36            ModuleReference::Core(v) => Ok(*v),
37            _ => Err(AbstractOsError::Assert(
38                "module reference not a core module.".to_string(),
39            )),
40        }
41    }
42
43    pub fn unwrap_native(&self) -> AbstractResult<Addr> {
44        match self {
45            ModuleReference::Native(addr) => Ok(addr.clone()),
46            _ => Err(AbstractOsError::Assert(
47                "module reference not a native module.".to_string(),
48            )),
49        }
50    }
51
52    pub fn unwrap_api(&self) -> AbstractResult<Addr> {
53        match self {
54            ModuleReference::Api(addr) => Ok(addr.clone()),
55            _ => Err(AbstractOsError::Assert(
56                "module reference not an api module.".to_string(),
57            )),
58        }
59    }
60
61    pub fn unwrap_app(&self) -> AbstractResult<u64> {
62        match self {
63            ModuleReference::App(v) => Ok(*v),
64            _ => Err(AbstractOsError::Assert(
65                "module reference not an app module.".to_string(),
66            )),
67        }
68    }
69
70    pub fn unwrap_standalone(&self) -> AbstractResult<u64> {
71        match self {
72            ModuleReference::Standalone(v) => Ok(*v),
73            _ => Err(AbstractOsError::Assert(
74                "module reference not a standalone module.".to_string(),
75            )),
76        }
77    }
78
79    /// Unwraps the module reference and returns the address of the module.
80    /// Throws an error if the module reference is not an address.
81    pub fn unwrap_addr(&self) -> AbstractResult<Addr> {
82        match self {
83            ModuleReference::Native(addr) => Ok(addr.clone()),
84            ModuleReference::Api(addr) => Ok(addr.clone()),
85            _ => Err(AbstractOsError::Assert(
86                "module reference not a native or api module.".to_string(),
87            )),
88        }
89    }
90}
91
92#[cfg(test)]
93mod test {
94    use super::*;
95    use cosmwasm_std::testing::mock_dependencies;
96    use speculoos::prelude::*;
97
98    #[test]
99    fn core() {
100        let core = ModuleReference::Core(1);
101        assert_eq!(core.unwrap_core().unwrap(), 1);
102        assert!(core.unwrap_native().is_err());
103        assert!(core.unwrap_api().is_err());
104        assert!(core.unwrap_app().is_err());
105        assert!(core.unwrap_standalone().is_err());
106    }
107    #[test]
108    fn native() {
109        let native = ModuleReference::Native(Addr::unchecked("addr"));
110        assert!(native.unwrap_core().is_err());
111        assert_eq!(native.unwrap_native().unwrap(), Addr::unchecked("addr"));
112        assert!(native.unwrap_api().is_err());
113        assert!(native.unwrap_app().is_err());
114        assert!(native.unwrap_standalone().is_err());
115    }
116
117    #[test]
118    fn api() {
119        let api = ModuleReference::Api(Addr::unchecked("addr"));
120        assert!(api.unwrap_core().is_err());
121        assert!(api.unwrap_native().is_err());
122        assert_eq!(api.unwrap_api().unwrap(), Addr::unchecked("addr"));
123        assert!(api.unwrap_app().is_err());
124        assert!(api.unwrap_standalone().is_err());
125    }
126
127    #[test]
128    fn app() {
129        let app = ModuleReference::App(1);
130        assert!(app.unwrap_core().is_err());
131        assert!(app.unwrap_native().is_err());
132        assert!(app.unwrap_api().is_err());
133        assert_eq!(app.unwrap_app().unwrap(), 1);
134        assert!(app.unwrap_standalone().is_err());
135    }
136
137    #[test]
138    fn standalone() {
139        let standalone = ModuleReference::Standalone(1);
140        assert!(standalone.unwrap_core().is_err());
141        assert!(standalone.unwrap_native().is_err());
142        assert!(standalone.unwrap_api().is_err());
143        assert!(standalone.unwrap_app().is_err());
144        assert_eq!(standalone.unwrap_standalone().unwrap(), 1);
145    }
146
147    #[test]
148    fn unwrap_addr() {
149        let native = ModuleReference::Native(Addr::unchecked("addr"));
150        assert_eq!(native.unwrap_addr().unwrap(), Addr::unchecked("addr"));
151        let api = ModuleReference::Api(Addr::unchecked("addr"));
152        assert_eq!(api.unwrap_addr().unwrap(), Addr::unchecked("addr"));
153
154        let core = ModuleReference::Core(1);
155        assert!(core.unwrap_addr().is_err());
156    }
157
158    #[test]
159    fn test_validate_happy_path() {
160        let deps = mock_dependencies();
161
162        let native = ModuleReference::Native(Addr::unchecked("addr"));
163        assert_that!(native.validate(deps.as_ref())).is_ok();
164
165        let api = ModuleReference::Api(Addr::unchecked("addr"));
166        assert_that!(api.validate(deps.as_ref())).is_ok();
167
168        let core = ModuleReference::Core(1);
169        assert_that!(core.validate(deps.as_ref())).is_ok();
170
171        let app = ModuleReference::App(1);
172        assert_that!(app.validate(deps.as_ref())).is_ok();
173
174        let standalone = ModuleReference::Standalone(1);
175        assert_that!(standalone.validate(deps.as_ref())).is_ok();
176    }
177
178    #[test]
179    fn test_validate_bad_address() {
180        let deps = mock_dependencies();
181
182        let native = ModuleReference::Native(Addr::unchecked(""));
183        assert_that!(native.validate(deps.as_ref())).is_err();
184
185        let api = ModuleReference::Api(Addr::unchecked(""));
186        assert_that!(api.validate(deps.as_ref())).is_err();
187    }
188}