abstract_std/objects/
module_reference.rs1use cosmwasm_std::{Addr, Deps};
2
3use crate::{error::AbstractError, AbstractResult};
4
5#[cosmwasm_schema::cw_serde]
6#[non_exhaustive]
7pub enum ModuleReference {
8 Account(u64),
10 Native(Addr),
12 Adapter(Addr),
14 App(u64),
16 Standalone(u64),
18 Service(Addr),
20}
21
22impl ModuleReference {
23 pub fn validate(&self, deps: Deps) -> AbstractResult<()> {
25 match self {
26 ModuleReference::Native(addr)
27 | ModuleReference::Adapter(addr)
28 | ModuleReference::Service(addr) => {
29 deps.api.addr_validate(addr.as_str())?;
30 }
31 _ => (),
32 };
33 Ok(())
34 }
35
36 pub fn unwrap_account(&self) -> AbstractResult<u64> {
37 match self {
38 ModuleReference::Account(v) => Ok(*v),
39 _ => Err(AbstractError::Assert(
40 "module reference not an account module.".to_string(),
41 )),
42 }
43 }
44
45 pub fn unwrap_native(&self) -> AbstractResult<Addr> {
46 match self {
47 ModuleReference::Native(addr) => Ok(addr.clone()),
48 _ => Err(AbstractError::Assert(
49 "module reference not a native module.".to_string(),
50 )),
51 }
52 }
53
54 pub fn unwrap_adapter(&self) -> AbstractResult<Addr> {
55 match self {
56 ModuleReference::Adapter(addr) => Ok(addr.clone()),
57 _ => Err(AbstractError::Assert(
58 "module reference not an api module.".to_string(),
59 )),
60 }
61 }
62
63 pub fn unwrap_app(&self) -> AbstractResult<u64> {
64 match self {
65 ModuleReference::App(v) => Ok(*v),
66 _ => Err(AbstractError::Assert(
67 "module reference not an app module.".to_string(),
68 )),
69 }
70 }
71
72 pub fn unwrap_standalone(&self) -> AbstractResult<u64> {
73 match self {
74 ModuleReference::Standalone(v) => Ok(*v),
75 _ => Err(AbstractError::Assert(
76 "module reference not a standalone module.".to_string(),
77 )),
78 }
79 }
80
81 pub fn unwrap_service(&self) -> AbstractResult<Addr> {
82 match self {
83 ModuleReference::Service(addr) => Ok(addr.clone()),
84 _ => Err(AbstractError::Assert(
85 "module reference not a service module.".to_string(),
86 )),
87 }
88 }
89
90 pub fn unwrap_addr(&self) -> AbstractResult<Addr> {
93 match self {
94 ModuleReference::Native(addr)
95 | ModuleReference::Adapter(addr)
96 | ModuleReference::Service(addr) => Ok(addr.clone()),
97 _ => Err(AbstractError::Assert(
98 "module reference not a native or api module.".to_string(),
99 )),
100 }
101 }
102
103 pub fn unwrap_code_id(&self) -> AbstractResult<u64> {
106 match self {
107 ModuleReference::Account(code_id)
108 | ModuleReference::App(code_id)
109 | ModuleReference::Standalone(code_id) => Ok(*code_id),
110 _ => Err(AbstractError::Assert(
111 "module reference not account, app or standalone".to_owned(),
112 )),
113 }
114 }
115}
116
117#[cfg(test)]
118mod test {
119 #![allow(clippy::needless_borrows_for_generic_args)]
120 use cosmwasm_std::testing::mock_dependencies;
121
122 use super::*;
123
124 #[coverage_helper::test]
125 fn core() {
126 let account = ModuleReference::Account(1);
127 assert_eq!(account.unwrap_account().unwrap(), 1);
128 assert!(account.unwrap_native().is_err());
129 assert!(account.unwrap_adapter().is_err());
130 assert!(account.unwrap_app().is_err());
131 assert!(account.unwrap_standalone().is_err());
132 assert!(account.unwrap_service().is_err());
133 }
134
135 #[coverage_helper::test]
136 fn native() {
137 let native = ModuleReference::Native(Addr::unchecked("addr"));
138 assert!(native.unwrap_account().is_err());
139 assert_eq!(native.unwrap_native().unwrap(), Addr::unchecked("addr"));
140 assert!(native.unwrap_adapter().is_err());
141 assert!(native.unwrap_app().is_err());
142 assert!(native.unwrap_standalone().is_err());
143 assert!(native.unwrap_service().is_err());
144 }
145
146 #[coverage_helper::test]
147 fn service() {
148 let service = ModuleReference::Service(Addr::unchecked("addr"));
149 assert!(service.unwrap_account().is_err());
150 assert!(service.unwrap_native().is_err());
151 assert!(service.unwrap_adapter().is_err());
152 assert!(service.unwrap_app().is_err());
153 assert!(service.unwrap_standalone().is_err());
154 assert_eq!(service.unwrap_service().unwrap(), Addr::unchecked("addr"));
155 }
156
157 #[coverage_helper::test]
158 fn adapter() {
159 let adapter = ModuleReference::Adapter(Addr::unchecked("addr"));
160 assert!(adapter.unwrap_account().is_err());
161 assert!(adapter.unwrap_native().is_err());
162 assert_eq!(adapter.unwrap_adapter().unwrap(), Addr::unchecked("addr"));
163 assert!(adapter.unwrap_app().is_err());
164 assert!(adapter.unwrap_standalone().is_err());
165 assert!(adapter.unwrap_service().is_err());
166 }
167
168 #[coverage_helper::test]
169 fn app() {
170 let app = ModuleReference::App(1);
171 assert!(app.unwrap_account().is_err());
172 assert!(app.unwrap_native().is_err());
173 assert!(app.unwrap_adapter().is_err());
174 assert_eq!(app.unwrap_app().unwrap(), 1);
175 assert!(app.unwrap_standalone().is_err());
176 assert!(app.unwrap_service().is_err());
177 }
178
179 #[coverage_helper::test]
180 fn standalone() {
181 let standalone = ModuleReference::Standalone(1);
182 assert!(standalone.unwrap_account().is_err());
183 assert!(standalone.unwrap_native().is_err());
184 assert!(standalone.unwrap_adapter().is_err());
185 assert!(standalone.unwrap_app().is_err());
186 assert_eq!(standalone.unwrap_standalone().unwrap(), 1);
187 assert!(standalone.unwrap_service().is_err());
188 }
189
190 #[coverage_helper::test]
191 fn unwrap_addr() {
192 let native = ModuleReference::Native(Addr::unchecked("addr"));
193 assert_eq!(native.unwrap_addr().unwrap(), Addr::unchecked("addr"));
194 let api = ModuleReference::Adapter(Addr::unchecked("addr"));
195 assert_eq!(api.unwrap_addr().unwrap(), Addr::unchecked("addr"));
196 let service = ModuleReference::Service(Addr::unchecked("addr"));
197 assert_eq!(service.unwrap_addr().unwrap(), Addr::unchecked("addr"));
198
199 let account = ModuleReference::Account(1);
200 assert!(account.unwrap_addr().is_err());
201 }
202
203 #[coverage_helper::test]
204 fn test_validate_happy_path() {
205 let deps = mock_dependencies();
206
207 let native = ModuleReference::Native(deps.api.addr_make("addr"));
208 assert!(native.validate(deps.as_ref()).is_ok());
209
210 let api = ModuleReference::Adapter(deps.api.addr_make("addr"));
211 assert!(api.validate(deps.as_ref()).is_ok());
212
213 let service = ModuleReference::Service(deps.api.addr_make("addr"));
214 assert!(service.validate(deps.as_ref()).is_ok());
215
216 let account = ModuleReference::Account(1);
217 assert!(account.validate(deps.as_ref()).is_ok());
218
219 let app = ModuleReference::App(1);
220 assert!(app.validate(deps.as_ref()).is_ok());
221
222 let standalone = ModuleReference::Standalone(1);
223 assert!(standalone.validate(deps.as_ref()).is_ok());
224 }
225
226 #[coverage_helper::test]
227 fn test_validate_bad_address() {
228 let deps = mock_dependencies();
229
230 let native = ModuleReference::Native(Addr::unchecked(""));
231 assert!(native.validate(deps.as_ref()).is_err());
232
233 let api = ModuleReference::Adapter(Addr::unchecked("abcde"));
234 assert!(api.validate(deps.as_ref()).is_err());
235
236 let service = ModuleReference::Service(Addr::unchecked("non_bech"));
237 assert!(service.validate(deps.as_ref()).is_err());
238 }
239}