use alloc::vec::Vec;
use codec::{Decode, DecodeAll, Encode, Output};
use scale_info::TypeInfo;
use Debug;
#[derive(Clone, Encode, Decode, Debug, TypeInfo)]
pub struct ViewFunctionId {
pub prefix: [u8; 16],
pub suffix: [u8; 16],
}
impl From<ViewFunctionId> for [u8; 32] {
fn from(value: ViewFunctionId) -> Self {
let mut output = [0u8; 32];
output[..16].copy_from_slice(&value.prefix);
output[16..].copy_from_slice(&value.suffix);
output
}
}
#[derive(Encode, Decode, Debug, TypeInfo)]
pub enum ViewFunctionDispatchError {
NotImplemented,
NotFound(ViewFunctionId),
Codec,
}
impl From<codec::Error> for ViewFunctionDispatchError {
fn from(_: codec::Error) -> Self {
ViewFunctionDispatchError::Codec
}
}
pub trait DispatchViewFunction {
fn dispatch_view_function<O: Output>(
id: &ViewFunctionId,
input: &mut &[u8],
output: &mut O,
) -> Result<(), ViewFunctionDispatchError>;
}
impl DispatchViewFunction for () {
fn dispatch_view_function<O: Output>(
_id: &ViewFunctionId,
_input: &mut &[u8],
_output: &mut O,
) -> Result<(), ViewFunctionDispatchError> {
Err(ViewFunctionDispatchError::NotImplemented)
}
}
pub trait ViewFunctionIdPrefix {
fn prefix() -> [u8; 16];
}
pub trait ViewFunctionIdSuffix {
const SUFFIX: [u8; 16];
}
pub trait ViewFunction: DecodeAll {
fn id() -> ViewFunctionId;
type ReturnType: Encode;
fn invoke(self) -> Self::ReturnType;
fn execute<O: Output>(
input: &mut &[u8],
output: &mut O,
) -> Result<(), ViewFunctionDispatchError> {
let view_function = Self::decode_all(input)?;
let result = view_function.invoke();
Encode::encode_to(&result, output);
Ok(())
}
}
pub mod runtime_api {
use super::*;
subsoil::api::decl_runtime_apis! {
#[api_version(1)]
pub trait RuntimeViewFunction {
fn execute_view_function(
query_id: ViewFunctionId,
input: Vec<u8>,
) -> Result<Vec<u8>, ViewFunctionDispatchError>;
}
}
}