use ergotree_ir::mir::byte_array_to_long::ByteArrayToLong;
use ergotree_ir::mir::value::Value;
use crate::eval::env::Env;
use crate::eval::EvalContext;
use crate::eval::EvalError;
use crate::eval::EvalError::UnexpectedValue;
use crate::eval::Evaluable;
use ergotree_ir::mir::constant::TryExtractInto;
impl Evaluable for ByteArrayToLong {
fn eval(&self, env: &Env, ctx: &mut EvalContext) -> Result<Value, EvalError> {
let input = self.input.eval(env, ctx)?.try_extract_into::<Vec<i8>>()?;
if input.len() < 8 {
return Err(UnexpectedValue(
"byteArrayToLong: array must contain at least 8 elements".into(),
));
}
Ok(((input[0] as i64) << 56
| (input[1] as i64) << 48
| (input[2] as i64) << 40
| (input[3] as i64) << 32
| (input[4] as i64) << 24
| (input[5] as i64) << 16
| (input[6] as i64) << 8
| (input[7] as i64))
.into())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::eval::tests::try_eval_out_wo_ctx;
fn eval_node(val: Vec<i8>) -> Result<i64, EvalError> {
let expr = ByteArrayToLong {
input: Box::new(val.into()),
}
.into();
try_eval_out_wo_ctx(&expr)
}
#[test]
fn eval_1() {
let res = eval_node(vec![0, 0, 0, 0, 0, 0, 0, 1]);
assert_eq!(res, Ok(1));
}
#[test]
fn eval_skip_tail() {
let res = eval_node(vec![0, 0, 0, 0, 0, 0, 0, 1, 0x42, 0x42]);
assert_eq!(res, Ok(1));
}
#[test]
fn eval_neg1() {
let res = eval_node(vec![-1; 8]);
assert_eq!(res, Ok(-1));
}
#[test]
fn fails_for_short() {
let res = eval_node(vec![0; 7]);
assert!(res.is_err());
}
}