casper_types/cl_value/
dictionary.rs

1use alloc::vec::Vec;
2
3use crate::{
4    bytesrepr::{self, Bytes, FromBytes, ToBytes},
5    CLType, CLTyped, CLValue, CLValueError, Key, StoredValue,
6};
7
8/// Wraps a [`CLValue`] for storage in a dictionary.
9///
10/// Note that we include the dictionary [`super::super::URef`] and key used to create the
11/// `Key::Dictionary` under which this value is stored.  This is to allow migration to a different
12/// key representation in the future.
13#[derive(Clone)]
14pub struct DictionaryValue {
15    /// Actual [`CLValue`] written to global state.
16    cl_value: CLValue,
17    /// [`URef`] seed bytes.
18    seed_uref_addr: Bytes,
19    /// Original key bytes.
20    dictionary_item_key_bytes: Bytes,
21}
22
23impl DictionaryValue {
24    /// Constructor.
25    pub fn new(
26        cl_value: CLValue,
27        seed_uref_addr: Vec<u8>,
28        dictionary_item_key_bytes: Vec<u8>,
29    ) -> Self {
30        Self {
31            cl_value,
32            seed_uref_addr: seed_uref_addr.into(),
33            dictionary_item_key_bytes: dictionary_item_key_bytes.into(),
34        }
35    }
36
37    /// Get a reference to the [`DictionaryValue`]'s wrapper's cl value.
38    pub fn into_cl_value(self) -> CLValue {
39        self.cl_value
40    }
41}
42
43impl CLTyped for DictionaryValue {
44    fn cl_type() -> CLType {
45        CLType::Any
46    }
47}
48
49impl FromBytes for DictionaryValue {
50    fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
51        let (cl_value, remainder) = FromBytes::from_bytes(bytes)?;
52        let (uref_addr, remainder) = FromBytes::from_bytes(remainder)?;
53        let (key_bytes, remainder) = FromBytes::from_bytes(remainder)?;
54        let dictionary_value = DictionaryValue {
55            cl_value,
56            seed_uref_addr: uref_addr,
57            dictionary_item_key_bytes: key_bytes,
58        };
59        Ok((dictionary_value, remainder))
60    }
61}
62
63impl ToBytes for DictionaryValue {
64    fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
65        let mut buffer = bytesrepr::allocate_buffer(self)?;
66        buffer.extend(self.cl_value.to_bytes()?);
67        buffer.extend(self.seed_uref_addr.to_bytes()?);
68        buffer.extend(self.dictionary_item_key_bytes.to_bytes()?);
69        Ok(buffer)
70    }
71
72    fn serialized_length(&self) -> usize {
73        self.cl_value.serialized_length()
74            + self.seed_uref_addr.serialized_length()
75            + self.dictionary_item_key_bytes.serialized_length()
76    }
77
78    fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
79        self.cl_value.write_bytes(writer)?;
80        self.seed_uref_addr.write_bytes(writer)?;
81        self.dictionary_item_key_bytes.write_bytes(writer)?;
82        Ok(())
83    }
84}
85
86/// Inspects `key` argument whether it contains a dictionary variant, and checks if `stored_value`
87/// contains a [`CLValue`], then it will attempt a conversion from the held clvalue into
88/// [`DictionaryValue`] and returns the real [`CLValue`] held by it.
89///
90/// For any other combination of `key` and `stored_value` it returns its unmodified value.
91pub fn handle_stored_dictionary_value(
92    key: Key,
93    stored_value: StoredValue,
94) -> Result<StoredValue, CLValueError> {
95    match (key, stored_value) {
96        (Key::Dictionary(_), StoredValue::CLValue(cl_value)) => {
97            let wrapped_cl_value: DictionaryValue = cl_value.into_t()?;
98            let cl_value = wrapped_cl_value.into_cl_value();
99            Ok(StoredValue::CLValue(cl_value))
100        }
101        (_, stored_value) => Ok(stored_value),
102    }
103}