pub mod payload;
use crate::error::{Error, MetadataError};
use crate::metadata::{DecodeWithMetadata, Metadata};
use alloc::borrow::ToOwned;
use alloc::format;
use alloc::string::String;
use alloc::vec::Vec;
use payload::Payload;
pub fn validate<P: Payload>(payload: &P, metadata: &Metadata) -> Result<(), Error> {
let Some(static_hash) = payload.validation_hash() else {
return Ok(());
};
let api_trait = metadata.runtime_api_trait_by_name_err(payload.trait_name())?;
let Some(api_method) = api_trait.method_by_name(payload.method_name()) else {
return Err(MetadataError::IncompatibleCodegen.into());
};
let runtime_hash = api_method.hash();
if static_hash != runtime_hash {
return Err(MetadataError::IncompatibleCodegen.into());
}
Ok(())
}
pub fn call_name<P: Payload>(payload: &P) -> String {
format!("{}_{}", payload.trait_name(), payload.method_name())
}
pub fn call_args<P: Payload>(payload: &P, metadata: &Metadata) -> Result<Vec<u8>, Error> {
payload.encode_args(metadata)
}
pub fn decode_value<P: Payload>(
bytes: &mut &[u8],
payload: &P,
metadata: &Metadata,
) -> Result<P::ReturnType, Error> {
let api_method = metadata
.runtime_api_trait_by_name_err(payload.trait_name())?
.method_by_name(payload.method_name())
.ok_or_else(|| MetadataError::RuntimeMethodNotFound(payload.method_name().to_owned()))?;
let val = <P::ReturnType as DecodeWithMetadata>::decode_with_metadata(
&mut &bytes[..],
api_method.output_ty(),
metadata,
)?;
Ok(val)
}