1use crate::app::CosmosRouter;
2use crate::error::{bail, AnyResult};
3use crate::AppResponse;
4use cosmwasm_std::{Addr, Api, Binary, BlockInfo, CustomQuery, Querier, Storage};
5use schemars::JsonSchema;
6use serde::de::DeserializeOwned;
7use std::fmt::Debug;
8use std::marker::PhantomData;
9
10pub trait Module {
12 type ExecT;
13 type QueryT;
14 type SudoT;
15
16 fn execute<ExecC, QueryC>(
19 &self,
20 api: &dyn Api,
21 storage: &mut dyn Storage,
22 router: &dyn CosmosRouter<ExecC = ExecC, QueryC = QueryC>,
23 block: &BlockInfo,
24 sender: Addr,
25 msg: Self::ExecT,
26 ) -> AnyResult<AppResponse>
27 where
28 ExecC: Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static,
29 QueryC: CustomQuery + DeserializeOwned + 'static;
30
31 fn query(
34 &self,
35 api: &dyn Api,
36 storage: &dyn Storage,
37 querier: &dyn Querier,
38 block: &BlockInfo,
39 request: Self::QueryT,
40 ) -> AnyResult<Binary>;
41
42 fn sudo<ExecC, QueryC>(
48 &self,
49 api: &dyn Api,
50 storage: &mut dyn Storage,
51 router: &dyn CosmosRouter<ExecC = ExecC, QueryC = QueryC>,
52 block: &BlockInfo,
53 msg: Self::SudoT,
54 ) -> AnyResult<AppResponse>
55 where
56 ExecC: Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static,
57 QueryC: CustomQuery + DeserializeOwned + 'static;
58}
59
60pub struct FailingModule<ExecT, QueryT, SudoT> {
61 module_type: String,
62 _t: PhantomData<(ExecT, QueryT, SudoT)>,
63}
64
65impl<ExecT, QueryT, SudoT> FailingModule<ExecT, QueryT, SudoT> {
66 pub fn new(module_type: &str) -> Self {
67 Self {
68 module_type: module_type.to_string(),
69 _t: PhantomData,
70 }
71 }
72}
73
74impl<ExecT, QueryT, SudoT> Module for FailingModule<ExecT, QueryT, SudoT>
75where
76 ExecT: Debug,
77 QueryT: Debug,
78 SudoT: Debug,
79{
80 type ExecT = ExecT;
81 type QueryT = QueryT;
82 type SudoT = SudoT;
83
84 fn execute<ExecC, QueryC>(
86 &self,
87 _api: &dyn Api,
88 _storage: &mut dyn Storage,
89 _router: &dyn CosmosRouter<ExecC = ExecC, QueryC = QueryC>,
90 _block: &BlockInfo,
91 sender: Addr,
92 msg: Self::ExecT,
93 ) -> AnyResult<AppResponse> {
94 bail!(
95 "Unexpected exec msg {:?} from {:?} on {} module",
96 msg,
97 sender,
98 self.module_type
99 )
100 }
101
102 fn query(
104 &self,
105 _api: &dyn Api,
106 _storage: &dyn Storage,
107 _querier: &dyn Querier,
108 _block: &BlockInfo,
109 request: Self::QueryT,
110 ) -> AnyResult<Binary> {
111 bail!(
112 "Unexpected custom query {:?} on {} module",
113 request,
114 self.module_type
115 )
116 }
117
118 fn sudo<ExecC, QueryC>(
120 &self,
121 _api: &dyn Api,
122 _storage: &mut dyn Storage,
123 _router: &dyn CosmosRouter<ExecC = ExecC, QueryC = QueryC>,
124 _block: &BlockInfo,
125 msg: Self::SudoT,
126 ) -> AnyResult<AppResponse> {
127 bail!(
128 "Unexpected sudo msg {:?} on {} module",
129 msg,
130 self.module_type
131 )
132 }
133}
134
135pub struct AcceptingModule<ExecT, QueryT, SudoT>(PhantomData<(ExecT, QueryT, SudoT)>);
136
137impl<ExecT, QueryT, SudoT> AcceptingModule<ExecT, QueryT, SudoT> {
138 pub fn new() -> Self {
139 Self(PhantomData)
140 }
141}
142
143impl<ExecT, QueryT, SudoT> Default for AcceptingModule<ExecT, QueryT, SudoT> {
144 fn default() -> Self {
145 Self::new()
146 }
147}
148
149impl<ExecT, QueryT, SudoT> Module for AcceptingModule<ExecT, QueryT, SudoT>
150where
151 ExecT: Debug,
152 QueryT: Debug,
153 SudoT: Debug,
154{
155 type ExecT = ExecT;
156 type QueryT = QueryT;
157 type SudoT = SudoT;
158
159 fn execute<ExecC, QueryC>(
161 &self,
162 _api: &dyn Api,
163 _storage: &mut dyn Storage,
164 _router: &dyn CosmosRouter<ExecC = ExecC, QueryC = QueryC>,
165 _block: &BlockInfo,
166 _sender: Addr,
167 _msg: Self::ExecT,
168 ) -> AnyResult<AppResponse> {
169 Ok(AppResponse::default())
170 }
171
172 fn query(
174 &self,
175 _api: &dyn Api,
176 _storage: &dyn Storage,
177 _querier: &dyn Querier,
178 _block: &BlockInfo,
179 _request: Self::QueryT,
180 ) -> AnyResult<Binary> {
181 Ok(Binary::default())
182 }
183
184 fn sudo<ExecC, QueryC>(
186 &self,
187 _api: &dyn Api,
188 _storage: &mut dyn Storage,
189 _router: &dyn CosmosRouter<ExecC = ExecC, QueryC = QueryC>,
190 _block: &BlockInfo,
191 _msg: Self::SudoT,
192 ) -> AnyResult<AppResponse> {
193 Ok(AppResponse::default())
194 }
195}