use super::runtime_api_type_info::{RuntimeApiInfo, RuntimeApiInfoError, RuntimeApiTypeInfo};
use crate::utils::{EncodableValues, IntoEncodableValues};
use alloc::format;
use alloc::string::String;
use alloc::vec::Vec;
use scale_type_resolver::TypeResolver;
#[non_exhaustive]
#[allow(missing_docs)]
#[derive(Debug, thiserror::Error)]
pub enum RuntimeApiInputsEncodeError {
#[error("Cannot get Runtime API info: {0}")]
CannotGetInfo(RuntimeApiInfoError<'static>),
#[error("Failed to encode Runtime API info: {0}")]
EncodeError(#[from] scale_encode::Error),
#[error("Wrong number of inputs provided: expected {num_inputs_expected}")]
WrongNumberOfInputsProvided {
num_inputs_expected: usize,
},
}
pub fn encode_runtime_api_name(trait_name: &str, method_name: &str) -> String {
format!("{trait_name}_{method_name}")
}
pub fn encode_runtime_api_inputs<Info, Resolver, Inputs>(
trait_name: &str,
method_name: &str,
keys: Inputs,
info: &Info,
type_resolver: &Resolver,
) -> Result<Vec<u8>, RuntimeApiInputsEncodeError>
where
Inputs: IntoEncodableValues,
Info: RuntimeApiTypeInfo,
Info::TypeId: Clone + core::fmt::Debug,
Resolver: TypeResolver<TypeId = Info::TypeId>,
{
let mut out = Vec::new();
encode_runtime_api_inputs_to(trait_name, method_name, keys, info, type_resolver, &mut out)?;
Ok(out)
}
pub fn encode_runtime_api_inputs_to<Info, Resolver, Inputs>(
trait_name: &str,
method_name: &str,
keys: Inputs,
info: &Info,
type_resolver: &Resolver,
out: &mut Vec<u8>,
) -> Result<(), RuntimeApiInputsEncodeError>
where
Inputs: IntoEncodableValues,
Info: RuntimeApiTypeInfo,
Info::TypeId: Clone + core::fmt::Debug,
Resolver: TypeResolver<TypeId = Info::TypeId>,
{
let runtime_api_info = info
.runtime_api_info(trait_name, method_name)
.map_err(|e| RuntimeApiInputsEncodeError::CannotGetInfo(e.into_owned()))?;
encode_runtime_api_inputs_with_info_to(keys, &runtime_api_info, type_resolver, out)
}
pub fn encode_runtime_api_inputs_with_info_to<Resolver, Inputs>(
inputs: Inputs,
runtime_api_info: &RuntimeApiInfo<<Resolver as TypeResolver>::TypeId>,
type_resolver: &Resolver,
out: &mut Vec<u8>,
) -> Result<(), RuntimeApiInputsEncodeError>
where
Inputs: IntoEncodableValues,
Resolver: TypeResolver,
<Resolver as TypeResolver>::TypeId: Clone + core::fmt::Debug,
{
if runtime_api_info.inputs.len() != inputs.num_encodable_values() {
return Err(RuntimeApiInputsEncodeError::WrongNumberOfInputsProvided {
num_inputs_expected: runtime_api_info.inputs.len(),
});
}
let mut inputs = inputs.into_encodable_values();
for input in &*runtime_api_info.inputs {
inputs
.encode_next_value_to(input.id.clone(), type_resolver, out)
.map_err(RuntimeApiInputsEncodeError::EncodeError)?;
}
Ok(())
}