1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/// This macro generates the boilerplate required to call into the
/// contract-specific logic from the entry-points to the Wasm module.
///
/// It should be invoked in a module scope(that is, not inside a function), and the argument to the macro
/// should be the name of a second rust module that is imported in the invocation scope.
/// The second module should export three functions with the following signatures:
/// ```
/// # use cosmwasm_std::{
/// #     Storage, Api, Querier, Extern, Env, StdResult, Binary, MessageInfo,
/// #     InitResult, HandleResult, QueryResult,
/// # };
/// #
/// # type InitMsg = ();
/// pub fn init<S: Storage, A: Api, Q: Querier>(
///     deps: &mut Extern<S, A, Q>,
///     env: Env,
///     info: MessageInfo,
///     msg: InitMsg,
/// ) -> InitResult {
/// #   Ok(Default::default())
/// }
///
/// # type HandleMsg = ();
/// pub fn handle<S: Storage, A: Api, Q: Querier>(
///     deps: &mut Extern<S, A, Q>,
///     env: Env,
///     info: MessageInfo,
///     msg: HandleMsg,
/// ) -> HandleResult {
/// #   Ok(Default::default())
/// }
///
/// # type QueryMsg = ();
/// pub fn query<S: Storage, A: Api, Q: Querier>(
///     deps: &Extern<S, A, Q>,
///     env: Env,
///     msg: QueryMsg,
/// ) -> QueryResult {
/// #   Ok(Binary(Vec::new()))
/// }
/// ```
/// Where `InitMsg`, `HandleMsg`, and `QueryMsg` are types that implement `DeserializeOwned + JsonSchema`
///
/// # Example
///
/// ```ignore
/// use contract; // The contract module
///
/// cosmwasm_std::create_entry_points!(contract);
/// ```
#[macro_export]
macro_rules! create_entry_points {
    (@migration; $contract:ident, true) => {
        #[no_mangle]
        extern "C" fn migrate(env_ptr: u32, info_ptr: u32, msg_ptr: u32) -> u32 {
            do_migrate(
                &$contract::migrate::<ExternalStorage, ExternalApi, ExternalQuerier>,
                env_ptr,
                info_ptr,
                msg_ptr,
            )
        }
    };

    (@migration; $contract:ident, false) => {};

    (@inner; $contract:ident, migration = $migration:tt) => {
        mod wasm {
            use super::$contract;
            use cosmwasm_std::{
                do_handle, do_init, do_migrate, do_query, ExternalApi, ExternalQuerier,
                ExternalStorage,
            };

            #[no_mangle]
            extern "C" fn init(env_ptr: u32, info_ptr: u32, msg_ptr: u32) -> u32 {
                do_init(
                    &$contract::init::<ExternalStorage, ExternalApi, ExternalQuerier>,
                    env_ptr,
                    info_ptr,
                    msg_ptr,
                )
            }

            #[no_mangle]
            extern "C" fn handle(env_ptr: u32, info_ptr: u32, msg_ptr: u32) -> u32 {
                do_handle(
                    &$contract::handle::<ExternalStorage, ExternalApi, ExternalQuerier>,
                    env_ptr,
                    info_ptr,
                    msg_ptr,
                )
            }

            #[no_mangle]
            extern "C" fn query(env_ptr: u32, msg_ptr: u32) -> u32 {
                do_query(
                    &$contract::query::<ExternalStorage, ExternalApi, ExternalQuerier>,
                    env_ptr,
                    msg_ptr,
                )
            }

            $crate::create_entry_points!(@migration; $contract, $migration);

            // Other C externs like cosmwasm_vm_version_4, allocate, deallocate are available
            // automatically because we `use cosmwasm_std`.
        }
    };

    ($contract:ident) => {
        $crate::create_entry_points!(@inner; $contract, migration = false);
    };
}

/// This macro is very similar to the `create_entry_points` macro, except it also requires the `migrate` method:
/// ```
/// # use cosmwasm_std::{
/// #     Storage, Api, Querier, Extern, Env, StdResult, Binary, MigrateResult, MessageInfo,
/// # };
/// # type MigrateMsg = ();
/// pub fn migrate<S: Storage, A: Api, Q: Querier>(
///     deps: &mut Extern<S, A, Q>,
///     _env: Env,
///     _info: MessageInfo,
///     msg: MigrateMsg,
/// ) -> MigrateResult {
/// #   Ok(Default::default())
/// }
/// ```
/// Where `MigrateMsg` is a type that implements `DeserializeOwned + JsonSchema`
///
/// # Example
///
/// ```ignore
/// use contract; // The contract module
///
/// cosmwasm_std::create_entry_points_with_migration!(contract);
/// ```
#[macro_export]
macro_rules! create_entry_points_with_migration {
    ($contract:ident) => {
        $crate::create_entry_points!(@inner; $contract, migration = true);
    };
}