1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use super::ConstantAddress;
use crate::{
client::OfflineClientT,
error::Error,
metadata::{
DecodeWithMetadata,
MetadataError,
},
Config,
};
use derivative::Derivative;
#[derive(Derivative)]
#[derivative(Clone(bound = "Client: Clone"))]
pub struct ConstantsClient<T, Client> {
client: Client,
_marker: std::marker::PhantomData<T>,
}
impl<T, Client> ConstantsClient<T, Client> {
pub fn new(client: Client) -> Self {
Self {
client,
_marker: std::marker::PhantomData,
}
}
}
impl<T: Config, Client: OfflineClientT<T>> ConstantsClient<T, Client> {
pub fn validate<Address: ConstantAddress>(
&self,
address: &Address,
) -> Result<(), Error> {
if let Some(actual_hash) = address.validation_hash() {
let expected_hash = self
.client
.metadata()
.constant_hash(address.pallet_name(), address.constant_name())?;
if actual_hash != expected_hash {
return Err(MetadataError::IncompatibleConstantMetadata(
address.pallet_name().into(),
address.constant_name().into(),
)
.into())
}
}
Ok(())
}
pub fn at<Address: ConstantAddress>(
&self,
address: &Address,
) -> Result<<Address::Target as DecodeWithMetadata>::Target, Error> {
let metadata = self.client.metadata();
self.validate(address)?;
let pallet = metadata.pallet(address.pallet_name())?;
let constant = pallet.constant(address.constant_name())?;
let value = Address::Target::decode_with_metadata(
&mut &*constant.value,
constant.ty.id(),
&metadata,
)?;
Ok(value)
}
}