use crate::fracpack::{Pack, UnpackOwned};
use crate::services::transact::ServiceMethod;
use crate::{get_result_bytes, native_raw, AccountNumber, Action, MethodNumber};
use serde::de::DeserializeOwned;
use serde::Serialize;
#[cfg(target_family = "wasm")]
static mut SERVICE: AccountNumber = AccountNumber::new(0);
#[cfg(target_family = "wasm")]
static mut SENDER: AccountNumber = AccountNumber::new(0);
#[cfg(target_family = "wasm")]
pub fn get_service() -> AccountNumber {
unsafe { SERVICE }
}
#[cfg(not(target_family = "wasm"))]
pub fn get_service() -> AccountNumber {
AccountNumber::new(0)
}
#[cfg(target_family = "wasm")]
pub fn get_sender() -> AccountNumber {
unsafe { SENDER }
}
#[cfg(not(target_family = "wasm"))]
pub fn get_sender() -> AccountNumber {
AccountNumber::new(0)
}
#[doc(hidden)]
#[cfg(target_family = "wasm")]
pub unsafe fn set_service(_acc: AccountNumber) {
SERVICE = _acc;
}
#[doc(hidden)]
#[cfg(target_family = "wasm")]
pub unsafe fn set_sender(_acc: AccountNumber) {
SENDER = _acc;
}
pub trait ProcessActionStruct {
type Output;
fn process<
Return: Serialize + DeserializeOwned,
ArgStruct: Pack + Serialize + DeserializeOwned,
>(
self,
) -> Self::Output;
}
pub trait WithActionStruct {
fn with_action_struct<P: ProcessActionStruct>(action: &str, process: P) -> Option<P::Output>;
}
pub trait Caller: Clone {
type ReturnsNothing;
type ReturnType<T: UnpackOwned>;
fn call_returns_nothing<Args: Pack>(
&self,
method: MethodNumber,
args: Args,
) -> Self::ReturnsNothing;
fn call<Ret: UnpackOwned, Args: Pack>(
&self,
method: MethodNumber,
args: Args,
) -> Self::ReturnType<Ret>;
}
#[derive(Clone, Default)]
pub struct JustSchema;
impl Caller for JustSchema {
type ReturnsNothing = ();
type ReturnType<T: UnpackOwned> = ();
fn call_returns_nothing<Args: Pack>(&self, _method: MethodNumber, _args: Args) {}
fn call<Ret: UnpackOwned, Args: Pack>(&self, _method: MethodNumber, _args: Args) {}
}
#[derive(Clone, Default)]
pub struct ServiceCaller {
pub sender: AccountNumber,
pub service: AccountNumber,
pub flags: u64,
}
impl Caller for ServiceCaller {
type ReturnsNothing = ();
type ReturnType<T: UnpackOwned> = T;
fn call_returns_nothing<Args: Pack>(&self, method: MethodNumber, args: Args) {
let act = Action {
sender: self.sender,
service: self.service,
method,
rawData: args.packed().into(),
}
.packed();
unsafe { native_raw::call(act.as_ptr(), act.len() as u32, self.flags) };
}
fn call<Ret: UnpackOwned, Args: Pack>(&self, method: MethodNumber, args: Args) -> Ret {
let act = Action {
sender: self.sender,
service: self.service,
method,
rawData: args.packed().into(),
}
.packed();
let ret = get_result_bytes(unsafe {
native_raw::call(act.as_ptr(), act.len() as u32, self.flags)
});
Ret::unpacked(&ret).unwrap()
}
}
#[derive(Clone, Default)]
pub struct ActionPacker {
pub sender: AccountNumber,
pub service: AccountNumber,
}
impl Caller for ActionPacker {
type ReturnsNothing = Action;
type ReturnType<T: UnpackOwned> = Action;
fn call_returns_nothing<Args: Pack>(&self, method: MethodNumber, args: Args) -> Action {
Action {
sender: self.sender,
service: self.service,
method,
rawData: args.packed().into(),
}
}
fn call<Ret: UnpackOwned, Args: Pack>(&self, method: MethodNumber, args: Args) -> Action {
Action {
sender: self.sender,
service: self.service,
method,
rawData: args.packed().into(),
}
}
}
#[derive(Clone, Default)]
pub struct RunAsCaller {
pub sender: AccountNumber,
pub service: AccountNumber,
pub allowed_actions: Vec<ServiceMethod>,
}
impl Caller for RunAsCaller {
type ReturnsNothing = ();
type ReturnType<T: UnpackOwned> = T;
fn call_returns_nothing<Args: Pack>(&self, method: MethodNumber, args: Args) {
let action = Action {
sender: self.sender,
service: self.service,
method,
rawData: args.packed().into(),
};
crate::services::transact::Wrapper::call().runAs(action, self.allowed_actions.clone());
}
fn call<Ret: UnpackOwned, Args: Pack>(&self, method: MethodNumber, args: Args) -> Ret {
let action = Action {
sender: self.sender,
service: self.service,
method,
rawData: args.packed().into(),
};
let ret =
crate::services::transact::Wrapper::call().runAs(action, self.allowed_actions.clone());
Ret::unpacked(&ret.0).unwrap()
}
}