use std::fmt;
use std::vec::Vec;
use schemars::JsonSchema;
use serde::{de::DeserializeOwned, Serialize};
use crate::errors::StdResult;
use crate::imports::{ExternalApi, ExternalQuerier, ExternalStorage};
use crate::memory::{alloc, consume_region, release_buffer, Region};
use crate::serde::{from_slice, to_vec};
use crate::traits::Extern;
use crate::{Env, HandleResult, InitResult, MigrateResult, QueryResponse, QueryResult};
#[cfg(feature = "staking")]
#[no_mangle]
extern "C" fn requires_staking() -> () {}
#[no_mangle]
extern "C" fn cosmwasm_vm_version_2() -> () {}
#[no_mangle]
extern "C" fn allocate(size: usize) -> u32 {
alloc(size) as u32
}
#[no_mangle]
extern "C" fn deallocate(pointer: u32) {
let _ = unsafe { consume_region(pointer as *mut Region) };
}
pub fn do_init<T, U>(
init_fn: &dyn Fn(
&mut Extern<ExternalStorage, ExternalApi, ExternalQuerier>,
Env,
T,
) -> InitResult<U>,
env_ptr: u32,
msg_ptr: u32,
) -> u32
where
T: DeserializeOwned + JsonSchema,
U: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
{
let res: InitResult<U> = _do_init(init_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
let v = to_vec(&res).unwrap();
release_buffer(v) as u32
}
pub fn do_handle<T, U>(
handle_fn: &dyn Fn(
&mut Extern<ExternalStorage, ExternalApi, ExternalQuerier>,
Env,
T,
) -> HandleResult<U>,
env_ptr: u32,
msg_ptr: u32,
) -> u32
where
T: DeserializeOwned + JsonSchema,
U: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
{
let res: HandleResult<U> =
_do_handle(handle_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
let v = to_vec(&res).unwrap();
release_buffer(v) as u32
}
pub fn do_query<T: DeserializeOwned + JsonSchema>(
query_fn: &dyn Fn(
&Extern<ExternalStorage, ExternalApi, ExternalQuerier>,
T,
) -> StdResult<QueryResponse>,
msg_ptr: u32,
) -> u32 {
let res: QueryResult = _do_query(query_fn, msg_ptr as *mut Region);
let v = to_vec(&res).unwrap();
release_buffer(v) as u32
}
pub fn do_migrate<T, U>(
migrate_fn: &dyn Fn(
&mut Extern<ExternalStorage, ExternalApi, ExternalQuerier>,
Env,
T,
) -> MigrateResult<U>,
env_ptr: u32,
msg_ptr: u32,
) -> u32
where
T: DeserializeOwned + JsonSchema,
U: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
{
let res: MigrateResult<U> =
_do_migrate(migrate_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
let v = to_vec(&res).unwrap();
release_buffer(v) as u32
}
fn _do_init<T, U>(
init_fn: &dyn Fn(
&mut Extern<ExternalStorage, ExternalApi, ExternalQuerier>,
Env,
T,
) -> InitResult<U>,
env_ptr: *mut Region,
msg_ptr: *mut Region,
) -> InitResult<U>
where
T: DeserializeOwned + JsonSchema,
U: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
{
let env: Vec<u8> = unsafe { consume_region(env_ptr) };
let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
let env: Env = from_slice(&env)?;
let msg: T = from_slice(&msg)?;
let mut deps = make_dependencies();
init_fn(&mut deps, env, msg)
}
fn _do_handle<T, U>(
handle_fn: &dyn Fn(
&mut Extern<ExternalStorage, ExternalApi, ExternalQuerier>,
Env,
T,
) -> HandleResult<U>,
env_ptr: *mut Region,
msg_ptr: *mut Region,
) -> HandleResult<U>
where
T: DeserializeOwned + JsonSchema,
U: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
{
let env: Vec<u8> = unsafe { consume_region(env_ptr) };
let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
let env: Env = from_slice(&env)?;
let msg: T = from_slice(&msg)?;
let mut deps = make_dependencies();
handle_fn(&mut deps, env, msg)
}
fn _do_query<T: DeserializeOwned + JsonSchema>(
query_fn: &dyn Fn(
&Extern<ExternalStorage, ExternalApi, ExternalQuerier>,
T,
) -> StdResult<QueryResponse>,
msg_ptr: *mut Region,
) -> StdResult<QueryResponse> {
let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
let msg: T = from_slice(&msg)?;
let deps = make_dependencies();
query_fn(&deps, msg)
}
fn _do_migrate<T, U>(
migrate_fn: &dyn Fn(
&mut Extern<ExternalStorage, ExternalApi, ExternalQuerier>,
Env,
T,
) -> MigrateResult<U>,
env_ptr: *mut Region,
msg_ptr: *mut Region,
) -> MigrateResult<U>
where
T: DeserializeOwned + JsonSchema,
U: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
{
let env: Vec<u8> = unsafe { consume_region(env_ptr) };
let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
let env: Env = from_slice(&env)?;
let msg: T = from_slice(&msg)?;
let mut deps = make_dependencies();
migrate_fn(&mut deps, env, msg)
}
fn make_dependencies() -> Extern<ExternalStorage, ExternalApi, ExternalQuerier> {
Extern {
storage: ExternalStorage::new(),
api: ExternalApi::new(),
querier: ExternalQuerier::new(),
}
}