subxt_core/constants/
address.rs

1// Copyright 2019-2024 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//! Construct addresses to access constants with.
6
7use crate::dynamic::DecodedValueThunk;
8use crate::metadata::DecodeWithMetadata;
9use alloc::borrow::Cow;
10use alloc::string::String;
11use derive_where::derive_where;
12
13/// This represents a constant address. Anything implementing this trait
14/// can be used to fetch constants.
15pub trait Address {
16    /// The target type of the value that lives at this address.
17    type Target: DecodeWithMetadata;
18
19    /// The name of the pallet that the constant lives under.
20    fn pallet_name(&self) -> &str;
21
22    /// The name of the constant in a given pallet.
23    fn constant_name(&self) -> &str;
24
25    /// An optional hash which, if present, will be checked against
26    /// the node metadata to confirm that the return type matches what
27    /// we are expecting.
28    fn validation_hash(&self) -> Option<[u8; 32]> {
29        None
30    }
31}
32
33/// This represents the address of a constant.
34#[derive_where(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
35pub struct DefaultAddress<ReturnTy> {
36    pallet_name: Cow<'static, str>,
37    constant_name: Cow<'static, str>,
38    constant_hash: Option<[u8; 32]>,
39    _marker: core::marker::PhantomData<ReturnTy>,
40}
41
42/// The type of address used by our static codegen.
43pub type StaticAddress<ReturnTy> = DefaultAddress<ReturnTy>;
44/// The type of address typically used to return dynamic constant values.
45pub type DynamicAddress = DefaultAddress<DecodedValueThunk>;
46
47impl<ReturnTy> DefaultAddress<ReturnTy> {
48    /// Create a new [`DefaultAddress`] to use to look up a constant.
49    pub fn new(pallet_name: impl Into<String>, constant_name: impl Into<String>) -> Self {
50        Self {
51            pallet_name: Cow::Owned(pallet_name.into()),
52            constant_name: Cow::Owned(constant_name.into()),
53            constant_hash: None,
54            _marker: core::marker::PhantomData,
55        }
56    }
57
58    /// Create a new [`DefaultAddress`] that will be validated
59    /// against node metadata using the hash given.
60    #[doc(hidden)]
61    pub fn new_static(
62        pallet_name: &'static str,
63        constant_name: &'static str,
64        hash: [u8; 32],
65    ) -> Self {
66        Self {
67            pallet_name: Cow::Borrowed(pallet_name),
68            constant_name: Cow::Borrowed(constant_name),
69            constant_hash: Some(hash),
70            _marker: core::marker::PhantomData,
71        }
72    }
73
74    /// Do not validate this constant prior to accessing it.
75    pub fn unvalidated(self) -> Self {
76        Self {
77            pallet_name: self.pallet_name,
78            constant_name: self.constant_name,
79            constant_hash: None,
80            _marker: self._marker,
81        }
82    }
83}
84
85impl<ReturnTy: DecodeWithMetadata> Address for DefaultAddress<ReturnTy> {
86    type Target = ReturnTy;
87
88    fn pallet_name(&self) -> &str {
89        &self.pallet_name
90    }
91
92    fn constant_name(&self) -> &str {
93        &self.constant_name
94    }
95
96    fn validation_hash(&self) -> Option<[u8; 32]> {
97        self.constant_hash
98    }
99}
100
101/// Construct a new dynamic constant lookup.
102pub fn dynamic(pallet_name: impl Into<String>, constant_name: impl Into<String>) -> DynamicAddress {
103    DynamicAddress::new(pallet_name, constant_name)
104}