clone_cw_multi_test/
module.rs

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
10/// Module interface.
11pub trait Module {
12    type ExecT;
13    type QueryT;
14    type SudoT;
15
16    /// Runs any [ExecT](Self::ExecT) message,
17    /// which can be called by any external actor or smart contract.
18    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    /// Runs any [QueryT](Self::QueryT) message,
32    /// which can be called by any external actor or smart contract.
33    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    /// Runs privileged actions, like minting tokens, or governance proposals.
43    /// This allows modules to have full access to these privileged actions,
44    /// that cannot be triggered by smart contracts.
45    ///
46    /// There is no sender, as this must be previously authorized before calling.
47    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    /// Runs any [ExecT](Self::ExecT) message, always returns an error.
85    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    /// Runs any [QueryT](Self::QueryT) message, always returns an error.
103    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    /// Runs any [SudoT](Self::SudoT) privileged action, always returns an error.
119    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    /// Runs any [ExecT](Self::ExecT) message, always returns a default response.
160    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    /// Runs any [QueryT](Self::QueryT) message, always returns an empty binary.
173    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    /// Runs any [SudoT](Self::SudoT) privileged action, always returns a default response.
185    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}