use std::convert::TryFrom;
use crate::{
ergo_box::{ConstErgoBoxPtr, ErgoBox, ErgoBoxPtr},
util::{const_ptr_as_ref, mut_ptr_as_mut},
Error,
};
use ergo_lib::{
ergo_chain_types::{Base16DecodedBytes, EcPoint},
ergotree_ir::{
base16_str::Base16Str,
chain::ergo_box::RegisterValue,
mir::constant::{TryExtractFrom, TryExtractInto},
serialization::SigmaSerializable,
sigma_protocol::sigma_boolean::ProveDlog,
},
};
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct Constant(pub(crate) ergo_lib::ergotree_ir::mir::constant::Constant);
pub type ConstantPtr = *mut Constant;
pub type ConstConstantPtr = *const Constant;
pub unsafe fn constant_from_base16_bytes(
bytes_str: &str,
constant_out: *mut ConstantPtr,
) -> Result<(), Error> {
let constant_out = mut_ptr_as_mut(constant_out, "constant_out")?;
let bytes = Base16DecodedBytes::try_from(bytes_str.to_string())?;
let register_value = RegisterValue::sigma_parse_bytes(bytes.as_ref());
let constant = register_value.as_constant()?.clone();
*constant_out = Box::into_raw(Box::new(Constant(constant)));
Ok(())
}
pub unsafe fn constant_to_base16_str(constant_ptr: ConstConstantPtr) -> Result<String, Error> {
let constant = const_ptr_as_ref(constant_ptr, "constant_ptr")?;
let s = constant.0.base16_str()?;
Ok(s)
}
pub unsafe fn constant_type_to_dbg_str(constant_ptr: ConstConstantPtr) -> Result<String, Error> {
let constant = const_ptr_as_ref(constant_ptr, "constant_ptr")?;
let s = format!("{:?}", constant.0.tpe);
Ok(s)
}
pub unsafe fn constant_value_to_dbg_str(constant_ptr: ConstConstantPtr) -> Result<String, Error> {
let constant = const_ptr_as_ref(constant_ptr, "constant_ptr")?;
let s = format!("{:?}", constant.0.v);
Ok(s)
}
pub unsafe fn constant_from_i16(value: i16, constant_out: *mut ConstantPtr) -> Result<(), Error> {
let constant_out = mut_ptr_as_mut(constant_out, "constant_out")?;
*constant_out = Box::into_raw(Box::new(Constant(value.into())));
Ok(())
}
pub unsafe fn constant_to_i16(constant_ptr: ConstConstantPtr) -> Result<i16, Error> {
let constant = const_ptr_as_ref(constant_ptr, "constant_ptr")?;
let i = i16::try_extract_from(constant.0.clone())?;
Ok(i)
}
pub unsafe fn constant_from_i32(value: i32, constant_out: *mut ConstantPtr) -> Result<(), Error> {
let constant_out = mut_ptr_as_mut(constant_out, "constant_out")?;
*constant_out = Box::into_raw(Box::new(Constant(value.into())));
Ok(())
}
pub unsafe fn constant_to_i32(constant_ptr: ConstConstantPtr) -> Result<i32, Error> {
let constant = const_ptr_as_ref(constant_ptr, "constant_ptr")?;
let i = i32::try_extract_from(constant.0.clone())?;
Ok(i)
}
pub unsafe fn constant_from_i64(value: i64, constant_out: *mut ConstantPtr) -> Result<(), Error> {
let constant_out = mut_ptr_as_mut(constant_out, "constant_out")?;
*constant_out = Box::into_raw(Box::new(Constant(value.into())));
Ok(())
}
pub unsafe fn constant_to_i64(constant_ptr: ConstConstantPtr) -> Result<i64, Error> {
let constant = const_ptr_as_ref(constant_ptr, "constant_ptr")?;
let i = i64::try_extract_from(constant.0.clone())?;
Ok(i)
}
pub unsafe fn constant_from_bytes(
bytes_ptr: *const u8,
len: usize,
constant_out: *mut ConstantPtr,
) -> Result<(), Error> {
let constant_out = mut_ptr_as_mut(constant_out, "constant_out")?;
let bytes = std::slice::from_raw_parts(bytes_ptr, len);
*constant_out = Box::into_raw(Box::new(Constant(bytes.to_vec().into())));
Ok(())
}
pub unsafe fn constant_bytes_len(constant_ptr: ConstConstantPtr) -> Result<usize, Error> {
let constant = const_ptr_as_ref(constant_ptr, "constant_ptr")?;
let len = Vec::<u8>::try_extract_from(constant.0.clone()).map(|v| v.len())?;
Ok(len)
}
pub unsafe fn constant_to_bytes(
constant_ptr: ConstConstantPtr,
output: *mut u8,
) -> Result<(), Error> {
let constant = const_ptr_as_ref(constant_ptr, "constant_ptr")?;
let src = Vec::<u8>::try_extract_from(constant.0.clone())?;
std::ptr::copy_nonoverlapping(src.as_ptr(), output, src.len());
Ok(())
}
pub unsafe fn constant_from_ecpoint_bytes(
bytes_ptr: *const u8,
len: usize,
constant_out: *mut ConstantPtr,
) -> Result<(), Error> {
let constant_out = mut_ptr_as_mut(constant_out, "constant_out")?;
let bytes = std::slice::from_raw_parts(bytes_ptr, len);
let ecp = EcPoint::sigma_parse_bytes(bytes)?;
let c: ergo_lib::ergotree_ir::mir::constant::Constant = ProveDlog::new(ecp).into();
*constant_out = Box::into_raw(Box::new(Constant(c)));
Ok(())
}
pub unsafe fn constant_from_ergo_box(
ergo_box_ptr: ConstErgoBoxPtr,
constant_out: *mut ConstantPtr,
) -> Result<(), Error> {
let ergo_box = const_ptr_as_ref(ergo_box_ptr, "ergo_box_ptr")?;
let constant_out = mut_ptr_as_mut(constant_out, "constant_out")?;
let c: ergo_lib::ergotree_ir::mir::constant::Constant = ergo_box.0.clone().into();
*constant_out = Box::into_raw(Box::new(Constant(c)));
Ok(())
}
pub unsafe fn constant_to_ergo_box(
constant_ptr: ConstConstantPtr,
ergo_box_out: *mut ErgoBoxPtr,
) -> Result<(), Error> {
let constant = const_ptr_as_ref(constant_ptr, "constant_ptr")?;
let ergo_box_out = mut_ptr_as_mut(ergo_box_out, "ergo_box_out")?;
let b = constant
.0
.clone()
.try_extract_into::<ergo_lib::ergotree_ir::chain::ergo_box::ErgoBox>()
.map(Into::into)?;
*ergo_box_out = Box::into_raw(Box::new(ErgoBox(b)));
Ok(())
}