use crate::error::NeoResult;
use crate::value::NeoValue;
pub trait NeoContract {
fn name() -> &'static str;
fn version() -> &'static str;
fn author() -> &'static str;
fn description() -> &'static str;
}
pub trait NeoContractEntry {
fn deploy() -> NeoResult<()>;
fn update() -> NeoResult<()>;
fn destroy() -> NeoResult<()>;
}
pub trait NeoContractMethodTrait {
fn name() -> &'static str;
fn parameters() -> &'static [&'static str];
fn return_type() -> &'static str;
fn execute(args: &[NeoValue]) -> NeoResult<NeoValue>;
}
pub trait FromNeoValue: Sized {
fn from_value(value: &NeoValue) -> NeoResult<Self>;
}
pub trait ContractCaller {
fn call_raw(
&self,
script_hash: &crate::bytestring::NeoByteString,
method: &str,
args: &[NeoValue],
call_flags: &crate::integer::NeoInteger,
) -> NeoResult<NeoValue>;
fn call_typed<T: FromNeoValue>(
&self,
script_hash: &crate::bytestring::NeoByteString,
method: &str,
args: &[NeoValue],
call_flags: &crate::integer::NeoInteger,
) -> NeoResult<T> {
let raw = self.call_raw(script_hash, method, args, call_flags)?;
T::from_value(&raw)
}
}
impl FromNeoValue for NeoValue {
fn from_value(value: &NeoValue) -> NeoResult<Self> {
Ok(value.clone())
}
}
impl FromNeoValue for () {
fn from_value(_value: &NeoValue) -> NeoResult<Self> {
Ok(())
}
}
impl FromNeoValue for bool {
fn from_value(value: &NeoValue) -> NeoResult<Self> {
value
.as_boolean()
.map(|b| b.as_bool())
.ok_or_else(|| crate::error::NeoError::new("expected Boolean"))
}
}
impl FromNeoValue for String {
fn from_value(value: &NeoValue) -> NeoResult<Self> {
let bytes = value
.as_byte_string()
.map(|bs| bs.as_slice().to_vec())
.or_else(|| value.as_string().map(|s| s.as_str().as_bytes().to_vec()))
.ok_or_else(|| crate::error::NeoError::new("expected String"))?;
String::from_utf8(bytes)
.map_err(|e| crate::error::NeoError::new(&format!("invalid UTF-8: {e}")))
}
}
impl FromNeoValue for Vec<u8> {
fn from_value(value: &NeoValue) -> NeoResult<Self> {
value
.as_byte_string()
.map(|bs| bs.as_slice().to_vec())
.ok_or_else(|| crate::error::NeoError::new("expected ByteArray"))
}
}
use crate::integer::NeoInteger;
impl FromNeoValue for NeoInteger {
fn from_value(value: &NeoValue) -> NeoResult<Self> {
value
.as_integer()
.cloned()
.ok_or_else(|| crate::error::NeoError::new("expected Integer"))
}
}
impl FromNeoValue for i64 {
fn from_value(value: &NeoValue) -> NeoResult<Self> {
let n = <NeoInteger as FromNeoValue>::from_value(value)?;
Ok(n.as_i64_saturating())
}
}