casper_types/contracts/
named_keys.rs1use alloc::{collections::BTreeMap, string::String, vec::Vec};
2
3#[cfg(feature = "datasize")]
4use datasize::DataSize;
5#[cfg(feature = "json-schema")]
6use schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8use serde_map_to_array::{BTreeMapToArray, KeyValueLabels};
9
10#[cfg(feature = "json-schema")]
11use crate::execution::execution_result_v1::NamedKey;
12use crate::{
13 bytesrepr::{self, FromBytes, ToBytes},
14 CLType, CLTyped, Key,
15};
16
17#[derive(Clone, Eq, PartialEq, Default, Serialize, Deserialize, Debug)]
19#[cfg_attr(feature = "datasize", derive(DataSize))]
20#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
21#[serde(deny_unknown_fields)]
22#[rustfmt::skip]
23pub struct NamedKeys(
24 #[serde(with = "BTreeMapToArray::<String, Key, Labels>")]
25 #[cfg_attr(feature = "json-schema", schemars(with = "Vec<NamedKey>"))]
26 BTreeMap<String, Key>,
27);
28
29impl NamedKeys {
30 pub const fn new() -> Self {
32 NamedKeys(BTreeMap::new())
33 }
34
35 pub fn into_inner(self) -> BTreeMap<String, Key> {
37 self.0
38 }
39
40 pub fn insert(&mut self, name: String, key: Key) -> Option<Key> {
45 self.0.insert(name, key)
46 }
47
48 pub fn append(&mut self, mut other: Self) {
50 self.0.append(&mut other.0)
51 }
52
53 pub fn remove(&mut self, name: &str) -> Option<Key> {
55 self.0.remove(name)
56 }
57
58 pub fn get(&self, name: &str) -> Option<&Key> {
60 self.0.get(name)
61 }
62
63 pub fn contains(&self, name: &str) -> bool {
65 self.0.contains_key(name)
66 }
67
68 pub fn names(&self) -> impl Iterator<Item = &String> {
70 self.0.keys()
71 }
72
73 pub fn keys(&self) -> impl Iterator<Item = &Key> {
75 self.0.values()
76 }
77
78 pub fn keys_mut(&mut self) -> impl Iterator<Item = &mut Key> {
80 self.0.values_mut()
81 }
82
83 pub fn iter(&self) -> impl Iterator<Item = (&String, &Key)> {
85 self.0.iter()
86 }
87
88 pub fn len(&self) -> usize {
90 self.0.len()
91 }
92
93 pub fn is_empty(&self) -> bool {
95 self.0.is_empty()
96 }
97}
98
99impl From<BTreeMap<String, Key>> for NamedKeys {
100 fn from(value: BTreeMap<String, Key>) -> Self {
101 NamedKeys(value)
102 }
103}
104
105impl ToBytes for NamedKeys {
106 fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
107 self.0.write_bytes(writer)
108 }
109
110 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
111 let mut buffer = bytesrepr::allocate_buffer(self)?;
112 self.write_bytes(&mut buffer)?;
113 Ok(buffer)
114 }
115
116 fn serialized_length(&self) -> usize {
117 self.0.serialized_length()
118 }
119}
120
121impl FromBytes for NamedKeys {
122 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
123 let (named_keys, remainder) = BTreeMap::<String, Key>::from_bytes(bytes)?;
124 Ok((NamedKeys(named_keys), remainder))
125 }
126}
127
128impl CLTyped for NamedKeys {
129 fn cl_type() -> CLType {
130 BTreeMap::<String, Key>::cl_type()
131 }
132}
133
134struct Labels;
135
136impl KeyValueLabels for Labels {
137 const KEY: &'static str = "name";
138 const VALUE: &'static str = "key";
139}
140
141#[cfg(test)]
142mod tests {
143 use rand::Rng;
144
145 use super::*;
146 use crate::testing::TestRng;
147
148 #[test]
151 fn should_be_backwards_compatible() {
152 let rng = &mut TestRng::new();
153 let mut named_keys = NamedKeys::new();
154 assert!(named_keys.insert("a".to_string(), rng.gen()).is_none());
155 assert!(named_keys.insert("bb".to_string(), rng.gen()).is_none());
156 assert!(named_keys.insert("ccc".to_string(), rng.gen()).is_none());
157
158 let serialized_old = bincode::serialize(&named_keys.0).unwrap();
159 let parsed_new = bincode::deserialize(&serialized_old).unwrap();
160 assert_eq!(named_keys, parsed_new);
161
162 let serialized_old = bytesrepr::serialize(&named_keys.0).unwrap();
163 let parsed_new = bytesrepr::deserialize(serialized_old).unwrap();
164 assert_eq!(named_keys, parsed_new);
165 }
166
167 #[test]
168 fn should_match_field_names() {
169 let mut named_keys = NamedKeys::new();
172 named_keys.insert("key".to_string(), Key::Hash([0u8; 32]));
173 assert_eq!(
174 serde_json::to_value(&named_keys).expect("should serialize"),
175 serde_json::json!([{
176 Labels::KEY: "key",
177 Labels::VALUE: "hash-0000000000000000000000000000000000000000000000000000000000000000"
178 }])
179 );
180 }
181}