use super::view_function_type_info::{
ViewFunctionInfo, ViewFunctionInfoError, ViewFunctionTypeInfo,
};
use crate::utils::{EncodableValues, IntoEncodableValues};
use alloc::vec::Vec;
use scale_type_resolver::TypeResolver;
#[non_exhaustive]
#[allow(missing_docs)]
#[derive(Debug, thiserror::Error)]
pub enum ViewFunctionInputsEncodeError {
#[error("Cannot get View Function info: {0}")]
CannotGetInfo(ViewFunctionInfoError<'static>),
#[error("Failed to encode View Function info: {0}")]
EncodeError(#[from] scale_encode::Error),
#[error("Wrong number of inputs provided; expected {num_inputs_expected}")]
WrongNumberOfInputsProvided {
num_inputs_expected: usize,
},
}
pub const RUNTIME_API_NAME: &str = "RuntimeViewFunction_execute_view_function";
pub fn encode_view_function_inputs<Info, Resolver, Inputs>(
pallet_name: &str,
function_name: &str,
inputs: Inputs,
info: &Info,
type_resolver: &Resolver,
) -> Result<Vec<u8>, ViewFunctionInputsEncodeError>
where
Inputs: IntoEncodableValues,
Info: ViewFunctionTypeInfo,
Info::TypeId: Clone + core::fmt::Debug,
Resolver: TypeResolver<TypeId = Info::TypeId>,
{
let mut out = Vec::with_capacity(32);
encode_view_function_inputs_to(
pallet_name,
function_name,
inputs,
info,
type_resolver,
&mut out,
)?;
Ok(out)
}
pub fn encode_view_function_inputs_to<Info, Resolver, Inputs>(
pallet_name: &str,
function_name: &str,
inputs: Inputs,
info: &Info,
type_resolver: &Resolver,
out: &mut Vec<u8>,
) -> Result<(), ViewFunctionInputsEncodeError>
where
Inputs: IntoEncodableValues,
Info: ViewFunctionTypeInfo,
Info::TypeId: Clone + core::fmt::Debug,
Resolver: TypeResolver<TypeId = Info::TypeId>,
{
let view_function_api_info = info
.view_function_info(pallet_name, function_name)
.map_err(|e| ViewFunctionInputsEncodeError::CannotGetInfo(e.into_owned()))?;
encode_view_function_inputs_with_info_to(inputs, &view_function_api_info, type_resolver, out)
}
pub fn encode_view_function_inputs_with_info_to<Resolver, Inputs>(
inputs: Inputs,
view_function_api_info: &ViewFunctionInfo<<Resolver as TypeResolver>::TypeId>,
type_resolver: &Resolver,
out: &mut Vec<u8>,
) -> Result<(), ViewFunctionInputsEncodeError>
where
Inputs: IntoEncodableValues,
Resolver: TypeResolver,
<Resolver as TypeResolver>::TypeId: Clone + core::fmt::Debug,
{
if view_function_api_info.inputs.len() != inputs.num_encodable_values() {
return Err(ViewFunctionInputsEncodeError::WrongNumberOfInputsProvided {
num_inputs_expected: view_function_api_info.inputs.len(),
});
}
out.extend_from_slice(&view_function_api_info.query_id);
let mut inputs = inputs.into_encodable_values();
for input in &*view_function_api_info.inputs {
inputs
.encode_next_value_to(input.id.clone(), type_resolver, out)
.map_err(ViewFunctionInputsEncodeError::EncodeError)?;
}
Ok(())
}