cw_multi_test/
custom_handler.rs

1//! # Custom message and query handler
2
3use crate::app::CosmosRouter;
4use crate::error::std_error_bail;
5use crate::{AppResponse, Module};
6use cosmwasm_std::{Addr, Api, Binary, BlockInfo, Empty, Querier, StdError, StdResult, Storage};
7use std::cell::{Ref, RefCell};
8use std::ops::Deref;
9use std::rc::Rc;
10
11/// A cache for messages and queries processes by the custom module.
12#[derive(Default, Clone)]
13pub struct CachingCustomHandlerState<ExecC, QueryC>
14where
15    ExecC: Default + Clone,
16    QueryC: Default + Clone,
17{
18    /// Cache for processes custom messages.
19    execs: Rc<RefCell<Vec<ExecC>>>,
20    /// Cache for processed custom queries.
21    queries: Rc<RefCell<Vec<QueryC>>>,
22}
23
24impl<ExecC, QueryC> CachingCustomHandlerState<ExecC, QueryC>
25where
26    ExecC: Default + Clone,
27    QueryC: Default + Clone,
28{
29    /// Creates a new [CachingCustomHandlerState].
30    pub fn new() -> Self {
31        Default::default()
32    }
33
34    /// Returns a slice of processed custom messages.
35    pub fn execs(&self) -> impl Deref<Target = [ExecC]> + '_ {
36        Ref::map(self.execs.borrow(), Vec::as_slice)
37    }
38
39    /// Returns a slice of processed custom queries.
40    pub fn queries(&self) -> impl Deref<Target = [QueryC]> + '_ {
41        Ref::map(self.queries.borrow(), Vec::as_slice)
42    }
43
44    /// Clears the cache.
45    pub fn reset(&self) {
46        self.execs.borrow_mut().clear();
47        self.queries.borrow_mut().clear();
48    }
49}
50
51/// Custom handler that stores all received messages and queries.
52///
53/// State is thin shared state, so it can be held after mock is passed to [App](crate::App) to read state.
54#[derive(Default, Clone)]
55pub struct CachingCustomHandler<ExecC, QueryC>
56where
57    ExecC: Default + Clone,
58    QueryC: Default + Clone,
59{
60    /// Cached state.
61    state: CachingCustomHandlerState<ExecC, QueryC>,
62}
63
64impl<ExecC, QueryC> CachingCustomHandler<ExecC, QueryC>
65where
66    ExecC: Default + Clone,
67    QueryC: Default + Clone,
68{
69    /// Creates a new [CachingCustomHandler].
70    pub fn new() -> Self {
71        Default::default()
72    }
73
74    /// Returns the cached state.
75    pub fn state(&self) -> CachingCustomHandlerState<ExecC, QueryC> {
76        self.state.clone()
77    }
78}
79
80impl<Exec, Query> Module for CachingCustomHandler<Exec, Query>
81where
82    Exec: Default + Clone,
83    Query: Default + Clone,
84{
85    type ExecT = Exec;
86    type QueryT = Query;
87    type SudoT = Empty;
88
89    fn execute<ExecC, QueryC>(
90        &self,
91        _api: &dyn Api,
92        _storage: &mut dyn Storage,
93        _router: &dyn CosmosRouter<ExecC = ExecC, QueryC = QueryC>,
94        _block: &BlockInfo,
95        _sender: Addr,
96        msg: Self::ExecT,
97    ) -> StdResult<AppResponse> {
98        self.state.execs.borrow_mut().push(msg);
99        Ok(AppResponse::default())
100    }
101
102    fn query(
103        &self,
104        _api: &dyn Api,
105        _storage: &dyn Storage,
106        _querier: &dyn Querier,
107        _block: &BlockInfo,
108        request: Self::QueryT,
109    ) -> StdResult<Binary> {
110        self.state.queries.borrow_mut().push(request);
111        Ok(Binary::default())
112    }
113
114    fn sudo<ExecC, QueryC>(
115        &self,
116        _api: &dyn Api,
117        _storage: &mut dyn Storage,
118        _router: &dyn CosmosRouter<ExecC = ExecC, QueryC = QueryC>,
119        _block: &BlockInfo,
120        msg: Self::SudoT,
121    ) -> StdResult<AppResponse> {
122        std_error_bail!("Unexpected custom sudo message {:?}", msg)
123    }
124}