use exonum::runtime::{CommonError, ExecutionContext, ExecutionError, InstanceId, MethodId};
use exonum_merkledb::BinaryValue;
use exonum_rust_runtime::{GenericCallMut, Interface, MethodDescriptor};
pub const CONFIGURE_INTERFACE_NAME: &str = "exonum.Configure";
const VERIFY_CONFIG_METHOD_ID: MethodId = 0;
const APPLY_CONFIG_METHOD_ID: MethodId = 1;
pub trait Configure {
type Params: BinaryValue;
fn verify_config(
&self,
context: ExecutionContext<'_>,
params: Self::Params,
) -> Result<(), ExecutionError>;
fn apply_config(
&self,
context: ExecutionContext<'_>,
params: Self::Params,
) -> Result<(), ExecutionError>;
}
impl<'a, T: BinaryValue> Interface<'a> for dyn Configure<Params = T> {
const INTERFACE_NAME: &'static str = CONFIGURE_INTERFACE_NAME;
fn dispatch(
&self,
context: ExecutionContext<'a>,
method: MethodId,
payload: &[u8],
) -> Result<(), ExecutionError> {
match method {
VERIFY_CONFIG_METHOD_ID => {
let params =
T::from_bytes(payload.into()).map_err(CommonError::malformed_arguments)?;
self.verify_config(context, params)
}
APPLY_CONFIG_METHOD_ID => {
let params =
T::from_bytes(payload.into()).map_err(CommonError::malformed_arguments)?;
self.apply_config(context, params)
}
_ => Err(CommonError::NoSuchMethod.into()),
}
}
}
pub(crate) trait ConfigureMut<Ctx> {
type Output;
fn verify_config(&mut self, context: Ctx, params: Vec<u8>) -> Self::Output;
fn apply_config(&mut self, context: Ctx, params: Vec<u8>) -> Self::Output;
}
impl ConfigureMut<InstanceId> for ExecutionContext<'_> {
type Output = Result<(), ExecutionError>;
fn verify_config(&mut self, instance_id: InstanceId, params: Vec<u8>) -> Self::Output {
const METHOD_DESCRIPTOR: MethodDescriptor<'static> =
MethodDescriptor::new(CONFIGURE_INTERFACE_NAME, 0);
self.generic_call_mut(instance_id, METHOD_DESCRIPTOR, params)
}
fn apply_config(&mut self, instance_id: InstanceId, params: Vec<u8>) -> Self::Output {
const METHOD_DESCRIPTOR: MethodDescriptor<'static> =
MethodDescriptor::new(CONFIGURE_INTERFACE_NAME, 1);
self.generic_call_mut(instance_id, METHOD_DESCRIPTOR, params)
}
}