#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
use alloc::string::String;
use alloc::vec::Vec;
use ink::env::call;
use ink::primitives::Hash;
use scale::{Decode, Encode};
#[derive(Debug, Encode, Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
pub enum GenericValue<S, B> {
String(S),
Bytes(B),
Undefined,
}
pub type RefValue<'a> = GenericValue<&'a str, &'a [u8]>;
pub type Value = GenericValue<String, Vec<u8>>;
pub type Output = Value;
fn js_delegate() -> Result<Hash, String> {
let system = pink::system::SystemRef::instance();
let delegate = system
.get_driver("JsDelegate2".into())
.ok_or("No JS driver found")?;
Ok(delegate.convert_to())
}
pub fn eval(script: &str, args: &[String]) -> Result<Output, String> {
eval_with(js_delegate()?, script, args)
}
pub fn eval_bytecode(code: &[u8], args: &[String]) -> Result<Output, String> {
eval_bytecode_with(js_delegate()?, code, args)
}
pub fn eval_all(codes: &[RefValue], args: &[String]) -> Result<Output, String> {
eval_all_with(js_delegate()?, codes, args)
}
pub fn eval_with(delegate: Hash, script: &str, args: &[String]) -> Result<Output, String> {
call::build_call::<pink::PinkEnvironment>()
.call_type(call::DelegateCall::new(delegate))
.exec_input(
call::ExecutionInput::new(call::Selector::new(ink::selector_bytes!("eval")))
.push_arg(script)
.push_arg(args),
)
.returns::<Result<Output, String>>()
.invoke()
}
pub fn eval_bytecode_with(
delegate: Hash,
script: &[u8],
args: &[String],
) -> Result<Output, String> {
call::build_call::<pink::PinkEnvironment>()
.call_type(call::DelegateCall::new(delegate))
.exec_input(
call::ExecutionInput::new(call::Selector::new(ink::selector_bytes!("eval_bytecode")))
.push_arg(script)
.push_arg(args),
)
.returns::<Result<Output, String>>()
.invoke()
}
pub fn eval_all_with(
delegate: Hash,
scripts: &[RefValue],
args: &[String],
) -> Result<Output, String> {
call::build_call::<pink::PinkEnvironment>()
.call_type(call::DelegateCall::new(delegate))
.exec_input(
call::ExecutionInput::new(call::Selector::new(ink::selector_bytes!("eval_all")))
.push_arg(scripts)
.push_arg(args),
)
.returns::<Result<Output, String>>()
.invoke()
}
pub fn compile(script: &str) -> Result<Vec<u8>, String> {
compile_with(js_delegate()?, script)
}
pub fn compile_with(delegate: Hash, script: &str) -> Result<Vec<u8>, String> {
call::build_call::<pink::PinkEnvironment>()
.call_type(call::DelegateCall::new(delegate))
.exec_input(
call::ExecutionInput::new(call::Selector::new(ink::selector_bytes!("compile")))
.push_arg(script),
)
.returns::<Result<Vec<u8>, String>>()
.invoke()
}
pub trait ConvertTo<To> {
fn convert_to(&self) -> To;
}
impl<F, T> ConvertTo<T> for F
where
F: AsRef<[u8; 32]>,
T: From<[u8; 32]>,
{
fn convert_to(&self) -> T {
(*self.as_ref()).into()
}
}