frame_decode/methods/
runtime_api_encoder.rs1use super::runtime_api_type_info::{RuntimeApiInfo, RuntimeApiInfoError, RuntimeApiTypeInfo};
17use crate::utils::{EncodableValues, IntoEncodableValues};
18use alloc::format;
19use alloc::string::String;
20use alloc::vec::Vec;
21use scale_type_resolver::TypeResolver;
22
23#[non_exhaustive]
25#[allow(missing_docs)]
26#[derive(Debug, thiserror::Error)]
27pub enum RuntimeApiInputsEncodeError {
28 #[error("Cannot get Runtime API info: {0}")]
29 CannotGetInfo(RuntimeApiInfoError<'static>),
30 #[error("Failed to encode Runtime API info: {0}")]
31 EncodeError(#[from] scale_encode::Error),
32 #[error("Wrong number of inputs provided: expected {num_inputs_expected}")]
33 WrongNumberOfInputsProvided {
34 num_inputs_expected: usize,
36 },
37}
38
39pub fn encode_runtime_api_name(trait_name: &str, method_name: &str) -> String {
41 format!("{trait_name}_{method_name}")
42}
43
44pub fn encode_runtime_api_inputs<Info, Resolver, Inputs>(
46 trait_name: &str,
47 method_name: &str,
48 keys: Inputs,
49 info: &Info,
50 type_resolver: &Resolver,
51) -> Result<Vec<u8>, RuntimeApiInputsEncodeError>
52where
53 Inputs: IntoEncodableValues,
54 Info: RuntimeApiTypeInfo,
55 Info::TypeId: Clone + core::fmt::Debug,
56 Resolver: TypeResolver<TypeId = Info::TypeId>,
57{
58 let mut out = Vec::new();
59 encode_runtime_api_inputs_to(trait_name, method_name, keys, info, type_resolver, &mut out)?;
60 Ok(out)
61}
62
63pub fn encode_runtime_api_inputs_to<Info, Resolver, Inputs>(
65 trait_name: &str,
66 method_name: &str,
67 keys: Inputs,
68 info: &Info,
69 type_resolver: &Resolver,
70 out: &mut Vec<u8>,
71) -> Result<(), RuntimeApiInputsEncodeError>
72where
73 Inputs: IntoEncodableValues,
74 Info: RuntimeApiTypeInfo,
75 Info::TypeId: Clone + core::fmt::Debug,
76 Resolver: TypeResolver<TypeId = Info::TypeId>,
77{
78 let runtime_api_info = info
79 .runtime_api_info(trait_name, method_name)
80 .map_err(|e| RuntimeApiInputsEncodeError::CannotGetInfo(e.into_owned()))?;
81
82 encode_runtime_api_inputs_with_info_to(keys, &runtime_api_info, type_resolver, out)
83}
84
85pub fn encode_runtime_api_inputs_with_info_to<Resolver, Inputs>(
91 inputs: Inputs,
92 runtime_api_info: &RuntimeApiInfo<<Resolver as TypeResolver>::TypeId>,
93 type_resolver: &Resolver,
94 out: &mut Vec<u8>,
95) -> Result<(), RuntimeApiInputsEncodeError>
96where
97 Inputs: IntoEncodableValues,
98 Resolver: TypeResolver,
99 <Resolver as TypeResolver>::TypeId: Clone + core::fmt::Debug,
100{
101 if runtime_api_info.inputs.len() != inputs.num_encodable_values() {
103 return Err(RuntimeApiInputsEncodeError::WrongNumberOfInputsProvided {
104 num_inputs_expected: runtime_api_info.inputs.len(),
105 });
106 }
107
108 let mut inputs = inputs.into_encodable_values();
110 for input in &*runtime_api_info.inputs {
111 inputs
112 .encode_next_value_to(input.id.clone(), type_resolver, out)
113 .map_err(RuntimeApiInputsEncodeError::EncodeError)?;
114 }
115
116 Ok(())
117}