cosmwasm_storage/
prefixed_storage.rs1use cosmwasm_std::{
2 storage_keys::{to_length_prefixed, to_length_prefixed_nested},
3 Storage,
4};
5#[cfg(feature = "iterator")]
6use cosmwasm_std::{Order, Record};
7
8#[cfg(feature = "iterator")]
9use crate::namespace_helpers::range_with_prefix;
10use crate::namespace_helpers::{get_with_prefix, remove_with_prefix, set_with_prefix};
11
12#[deprecated(
14 note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls."
15)]
16pub fn prefixed<'a>(storage: &'a mut dyn Storage, namespace: &[u8]) -> PrefixedStorage<'a> {
17 PrefixedStorage::new(storage, namespace)
18}
19
20#[deprecated(
22 note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls."
23)]
24pub fn prefixed_read<'a>(
25 storage: &'a dyn Storage,
26 namespace: &[u8],
27) -> ReadonlyPrefixedStorage<'a> {
28 ReadonlyPrefixedStorage::new(storage, namespace)
29}
30
31#[deprecated(
32 note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls."
33)]
34pub struct PrefixedStorage<'a> {
35 storage: &'a mut dyn Storage,
36 prefix: Vec<u8>,
37}
38
39impl<'a> PrefixedStorage<'a> {
40 pub fn new(storage: &'a mut dyn Storage, namespace: &[u8]) -> Self {
41 PrefixedStorage {
42 storage,
43 prefix: to_length_prefixed(namespace),
44 }
45 }
46
47 pub fn multilevel(storage: &'a mut dyn Storage, namespaces: &[&[u8]]) -> Self {
50 PrefixedStorage {
51 storage,
52 prefix: to_length_prefixed_nested(namespaces),
53 }
54 }
55}
56
57impl<'a> Storage for PrefixedStorage<'a> {
58 fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
59 get_with_prefix(self.storage, &self.prefix, key)
60 }
61
62 fn set(&mut self, key: &[u8], value: &[u8]) {
63 set_with_prefix(self.storage, &self.prefix, key, value);
64 }
65
66 fn remove(&mut self, key: &[u8]) {
67 remove_with_prefix(self.storage, &self.prefix, key);
68 }
69
70 #[cfg(feature = "iterator")]
71 fn range<'b>(
74 &'b self,
75 start: Option<&[u8]>,
76 end: Option<&[u8]>,
77 order: Order,
78 ) -> Box<dyn Iterator<Item = Record> + 'b> {
79 range_with_prefix(self.storage, &self.prefix, start, end, order)
80 }
81}
82
83#[deprecated(
84 note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls."
85)]
86pub struct ReadonlyPrefixedStorage<'a> {
87 storage: &'a dyn Storage,
88 prefix: Vec<u8>,
89}
90
91impl<'a> ReadonlyPrefixedStorage<'a> {
92 pub fn new(storage: &'a dyn Storage, namespace: &[u8]) -> Self {
93 ReadonlyPrefixedStorage {
94 storage,
95 prefix: to_length_prefixed(namespace),
96 }
97 }
98
99 pub fn multilevel(storage: &'a dyn Storage, namespaces: &[&[u8]]) -> Self {
102 ReadonlyPrefixedStorage {
103 storage,
104 prefix: to_length_prefixed_nested(namespaces),
105 }
106 }
107}
108
109impl<'a> Storage for ReadonlyPrefixedStorage<'a> {
110 fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
111 get_with_prefix(self.storage, &self.prefix, key)
112 }
113
114 fn set(&mut self, _key: &[u8], _value: &[u8]) {
115 unimplemented!();
116 }
117
118 fn remove(&mut self, _key: &[u8]) {
119 unimplemented!();
120 }
121
122 #[cfg(feature = "iterator")]
123 fn range<'b>(
125 &'b self,
126 start: Option<&[u8]>,
127 end: Option<&[u8]>,
128 order: Order,
129 ) -> Box<dyn Iterator<Item = Record> + 'b> {
130 range_with_prefix(self.storage, &self.prefix, start, end, order)
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use super::*;
137 use cosmwasm_std::testing::MockStorage;
138
139 #[test]
140 fn prefixed_storage_set_and_get() {
141 let mut storage = MockStorage::new();
142
143 let mut s1 = PrefixedStorage::new(&mut storage, b"foo");
145 s1.set(b"bar", b"gotcha");
146 assert_eq!(storage.get(b"\x00\x03foobar").unwrap(), b"gotcha".to_vec());
147
148 let s2 = PrefixedStorage::new(&mut storage, b"foo");
150 assert_eq!(s2.get(b"bar"), Some(b"gotcha".to_vec()));
151 assert_eq!(s2.get(b"elsewhere"), None);
152 }
153
154 #[test]
155 fn prefixed_storage_multilevel_set_and_get() {
156 let mut storage = MockStorage::new();
157
158 let mut bar = PrefixedStorage::multilevel(&mut storage, &[b"foo", b"bar"]);
160 bar.set(b"baz", b"winner");
161 assert_eq!(
162 storage.get(b"\x00\x03foo\x00\x03barbaz").unwrap(),
163 b"winner".to_vec()
164 );
165
166 let bar = PrefixedStorage::multilevel(&mut storage, &[b"foo", b"bar"]);
168 assert_eq!(bar.get(b"baz"), Some(b"winner".to_vec()));
169 assert_eq!(bar.get(b"elsewhere"), None);
170 }
171
172 #[test]
173 fn readonly_prefixed_storage_get() {
174 let mut storage = MockStorage::new();
175 storage.set(b"\x00\x03foobar", b"gotcha");
176
177 let s1 = ReadonlyPrefixedStorage::new(&storage, b"foo");
179 assert_eq!(s1.get(b"bar"), Some(b"gotcha".to_vec()));
180 assert_eq!(s1.get(b"elsewhere"), None);
181
182 let s2 = ReadonlyPrefixedStorage::new(&storage, b"fo");
184 assert_eq!(s2.get(b"obar"), None);
185 }
186
187 #[test]
188 fn readonly_prefixed_storage_multilevel_get() {
189 let mut storage = MockStorage::new();
190 storage.set(b"\x00\x03foo\x00\x03barbaz", b"winner");
191
192 let bar = ReadonlyPrefixedStorage::multilevel(&storage, &[b"foo", b"bar"]);
193 assert_eq!(bar.get(b"baz"), Some(b"winner".to_vec()));
194 assert_eq!(bar.get(b"elsewhere"), None);
195 }
196}