use super::*;
use console::program::FinalizeType;
impl<N: Network> RegistersLoad<N> for FinalizeRegisters<N> {
#[inline]
fn load(&self, stack: &(impl StackMatches<N> + StackProgram<N>), operand: &Operand<N>) -> Result<Value<N>> {
let register = match operand {
Operand::Literal(literal) => return Ok(Value::Plaintext(Plaintext::from(literal))),
Operand::Register(register) => register,
Operand::ProgramID(program_id) => {
return Ok(Value::Plaintext(Plaintext::from(Literal::Address(program_id.to_address()?))));
}
Operand::Signer => bail!("Forbidden operation: Cannot use 'self.signer' in 'finalize'"),
Operand::Caller => bail!("Forbidden operation: Cannot use 'self.caller' in 'finalize'"),
Operand::BlockHeight => {
return Ok(Value::Plaintext(Plaintext::from(Literal::U32(U32::new(self.state.block_height())))));
}
Operand::NetworkID => {
return Ok(Value::Plaintext(Plaintext::from(Literal::U16(U16::new(N::ID)))));
}
};
let value = self.registers.get(®ister.locator()).ok_or_else(|| anyhow!("'{register}' does not exist"))?;
let value = match register {
Register::Locator(..) => value.clone(),
Register::Access(_, ref path) => value.find(path)?,
};
match (self.finalize_types.get_type(stack, register), &value) {
(Ok(FinalizeType::Plaintext(plaintext_type)), Value::Plaintext(plaintext_value)) => {
stack.matches_plaintext(plaintext_value, &plaintext_type)?
}
(Ok(FinalizeType::Future(locator)), Value::Future(future)) => stack.matches_future(future, &locator)?,
(Ok(finalize_type), stack_value) => bail!(
"Attempted to load a '{stack_value}' value from a register '{register}' of type '{finalize_type}' in a finalize scope",
),
(Err(error), _) => bail!("Register '{register}' is not a member of the function: {error}"),
};
Ok(value)
}
}