1use crate::response::Response;
4use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, StdError, StdResult};
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7use std::fmt::Display;
8
9pub trait Module {
17 type InstantiateMsg: for<'a> Deserialize<'a>;
19 type ExecuteMsg: for<'a> Deserialize<'a>;
23 type QueryMsg: for<'a> Deserialize<'a>;
26 type QueryResp: Serialize;
28 type Error: Display;
31
32 fn instantiate(
35 &mut self,
36 deps: &mut DepsMut,
37 env: &Env,
38 info: &MessageInfo,
39 msg: Self::InstantiateMsg,
40 ) -> Result<Response, Self::Error>;
41 fn execute(
44 &mut self,
45 deps: &mut DepsMut,
46 env: Env,
47 info: MessageInfo,
48 msg: Self::ExecuteMsg,
49 ) -> Result<Response, Self::Error>;
50 fn query(
53 &self,
54 deps: &Deps,
55 env: Env,
56 msg: Self::QueryMsg,
57 ) -> Result<Self::QueryResp, Self::Error>;
58}
59
60pub trait GenericModule {
67 fn instantiate_value(
69 &mut self,
70 deps: &mut DepsMut,
71 env: &Env,
72 info: &MessageInfo,
73 msg: &Value,
74 ) -> Result<Response, String>;
75 fn execute_value(
77 &mut self,
78 deps: &mut DepsMut,
79 env: Env,
80 info: MessageInfo,
81 msg: &Value,
82 ) -> Result<Response, String>;
83 fn query_value(&self, deps: &Deps, env: Env, msg: &Value) -> StdResult<Binary>;
85}
86
87impl<T, A, B, C, D, E> GenericModule for T
89where
90 A: for<'de> Deserialize<'de>,
91 B: for<'de> Deserialize<'de>,
92 C: for<'de> Deserialize<'de>,
93 D: Serialize,
94 E: Display,
95 T: Module<InstantiateMsg = A, ExecuteMsg = B, QueryMsg = C, QueryResp = D, Error = E>,
96{
97 fn instantiate_value(
98 &mut self,
99 deps: &mut DepsMut,
100 env: &Env,
101 info: &MessageInfo,
102 msg: &Value,
103 ) -> Result<Response, String> {
104 let parsed_msg = serde_json::from_value(msg.clone()).map_err(|e| e.to_string())?;
105 self.instantiate(deps, env, info, parsed_msg)
106 .map_err(|e| e.to_string())
107 }
108
109 fn execute_value(
110 &mut self,
111 deps: &mut DepsMut,
112 env: Env,
113 info: MessageInfo,
114 msg: &Value,
115 ) -> Result<Response, String> {
116 let parsed_msg = serde_json::from_value(msg.clone()).map_err(|e| e.to_string())?;
117 self.execute(deps, env, info, parsed_msg)
118 .map_err(|e| e.to_string())
119 }
120
121 fn query_value(&self, deps: &Deps, env: Env, msg: &Value) -> StdResult<Binary> {
122 let parsed_msg = serde_json::from_value(msg.clone())
123 .map_err(|e| StdError::generic_err(e.to_string()))?;
124 let res = self
125 .query(deps, env, parsed_msg)
126 .map_err(|e| StdError::generic_err(e.to_string()))?;
127 cosmwasm_std::to_binary(&res)
128 }
129}