gear_subxt/dynamic.rs
1// Copyright 2019-2023 Parity Technologies (UK) Ltd.
2// This file is dual-licensed as Apache-2.0 or GPL-3.0.
3// see LICENSE for license details.
4
5//! This module provides the entry points to create dynamic
6//! transactions, storage and constant lookups.
7
8use crate::{
9 error::Error,
10 metadata::{DecodeWithMetadata, Metadata},
11};
12use scale_decode::DecodeAsType;
13
14pub use scale_value::{At, Value};
15
16/// A [`scale_value::Value`] type endowed with contextual information
17/// regarding what type was used to decode each part of it. This implements
18/// [`crate::metadata::DecodeWithMetadata`], and is used as a return type
19/// for dynamic requests.
20pub type DecodedValue = scale_value::Value<scale_value::scale::TypeId>;
21
22// Submit dynamic transactions.
23pub use crate::tx::dynamic as tx;
24
25// Lookup constants dynamically.
26pub use crate::constants::dynamic as constant;
27
28// Lookup storage values dynamically.
29pub use crate::storage::{dynamic as storage, dynamic_root as storage_root};
30
31// Execute runtime API function call dynamically.
32pub use crate::runtime_api::dynamic as runtime_api_call;
33
34/// This is the result of making a dynamic request to a node. From this,
35/// we can return the raw SCALE bytes that we were handed back, or we can
36/// complete the decoding of the bytes into a [`DecodedValue`] type.
37pub struct DecodedValueThunk {
38 type_id: u32,
39 metadata: Metadata,
40 scale_bytes: Vec<u8>,
41}
42
43impl DecodeWithMetadata for DecodedValueThunk {
44 fn decode_with_metadata(
45 bytes: &mut &[u8],
46 type_id: u32,
47 metadata: &Metadata,
48 ) -> Result<Self, Error> {
49 let mut v = Vec::with_capacity(bytes.len());
50 v.extend_from_slice(bytes);
51 *bytes = &[];
52 Ok(DecodedValueThunk {
53 type_id,
54 metadata: metadata.clone(),
55 scale_bytes: v,
56 })
57 }
58}
59
60impl DecodedValueThunk {
61 /// Return the SCALE encoded bytes handed back from the node.
62 pub fn into_encoded(self) -> Vec<u8> {
63 self.scale_bytes
64 }
65 /// Return the SCALE encoded bytes handed back from the node without taking ownership of them.
66 pub fn encoded(&self) -> &[u8] {
67 &self.scale_bytes
68 }
69 /// Decode the SCALE encoded storage entry into a dynamic [`DecodedValue`] type.
70 pub fn to_value(&self) -> Result<DecodedValue, Error> {
71 let val = DecodedValue::decode_as_type(
72 &mut &*self.scale_bytes,
73 self.type_id,
74 self.metadata.types(),
75 )?;
76 Ok(val)
77 }
78}