1#![cfg(feature = "iterator")]
3
4use std::marker::PhantomData;
5
6use serde::de::DeserializeOwned;
7use serde::{Deserialize, Serialize};
8
9use cosmwasm_std::{from_json, Binary, Order, Record, StdError, StdResult, Storage};
10
11use crate::bound::PrefixBound;
12use crate::de::KeyDeserialize;
13use crate::indexes::IndexPrefix;
14use crate::iter_helpers::deserialize_kv;
15use crate::map::Map;
16use crate::prefix::namespaced_prefix_range;
17use crate::{Bound, Index, Prefixer, PrimaryKey};
18
19#[derive(Deserialize, Serialize)]
21pub(crate) struct UniqueRef<T> {
22 pk: Binary,
24 value: T,
25}
26
27pub struct UniqueIndex<'a, IK, T, PK> {
31 index: fn(&T) -> IK,
32 idx_map: Map<IK, UniqueRef<T>>,
33 idx_namespace: &'a [u8],
34 phantom: PhantomData<PK>,
35}
36
37impl<IK, T, PK> UniqueIndex<'_, IK, T, PK> {
38 pub const fn new(idx_fn: fn(&T) -> IK, idx_namespace: &'static str) -> Self {
56 UniqueIndex {
57 index: idx_fn,
58 idx_map: Map::new(idx_namespace),
59 idx_namespace: idx_namespace.as_bytes(),
60 phantom: PhantomData,
61 }
62 }
63}
64
65impl<'a, IK, T, PK> Index<T> for UniqueIndex<'a, IK, T, PK>
66where
67 T: Serialize + DeserializeOwned + Clone,
68 IK: PrimaryKey<'a>,
69{
70 fn save(&self, store: &mut dyn Storage, pk: &[u8], data: &T) -> StdResult<()> {
71 let idx = (self.index)(data);
72 self.idx_map
74 .update(store, idx, |existing| -> StdResult<_> {
75 match existing {
76 Some(_) => Err(StdError::msg("Violates unique constraint on index")),
77 None => Ok(UniqueRef::<T> {
78 pk: pk.into(),
79 value: data.clone(),
80 }),
81 }
82 })?;
83 Ok(())
84 }
85
86 fn remove(&self, store: &mut dyn Storage, _pk: &[u8], old_data: &T) -> StdResult<()> {
87 let idx = (self.index)(old_data);
88 self.idx_map.remove(store, idx);
89 Ok(())
90 }
91}
92
93fn deserialize_unique_v<T: DeserializeOwned>(kv: Record) -> StdResult<Record<T>> {
94 let (_, v) = kv;
95 let t = from_json::<UniqueRef<T>>(&v)?;
96 Ok((t.pk.into(), t.value))
97}
98
99fn deserialize_unique_kv<K: KeyDeserialize, T: DeserializeOwned>(
100 kv: Record,
101) -> StdResult<(K::Output, T)> {
102 let (_, v) = kv;
103 let t = from_json::<UniqueRef<T>>(&v)?;
104 Ok((K::from_vec(t.pk.into())?, t.value))
105}
106
107impl<'a, IK, T, PK> UniqueIndex<'a, IK, T, PK>
108where
109 T: Serialize + DeserializeOwned + Clone,
110 IK: PrimaryKey<'a>,
111{
112 pub fn index_key(&self, k: IK) -> Vec<u8> {
113 k.joined_key()
114 }
115
116 fn no_prefix_raw(&self) -> IndexPrefix<Vec<u8>, T, IK> {
117 IndexPrefix::with_deserialization_functions(
118 self.idx_namespace,
119 &[],
120 &[],
121 |_, _, kv| deserialize_unique_v(kv),
122 |_, _, kv| deserialize_unique_v(kv),
123 )
124 }
125
126 pub fn item(&self, store: &dyn Storage, idx: IK) -> StdResult<Option<Record<T>>> {
128 let data = self
129 .idx_map
130 .may_load(store, idx)?
131 .map(|i| (i.pk.into(), i.value));
132 Ok(data)
133 }
134}
135
136impl<'a, IK, T, PK> UniqueIndex<'a, IK, T, PK>
138where
139 T: Serialize + DeserializeOwned + Clone,
140 IK: PrimaryKey<'a>,
141{
142 pub fn range_raw<'c>(
145 &self,
146 store: &'c dyn Storage,
147 min: Option<Bound<'a, IK>>,
148 max: Option<Bound<'a, IK>>,
149 order: Order,
150 ) -> Box<dyn Iterator<Item = StdResult<Record<T>>> + 'c>
151 where
152 T: 'c,
153 {
154 self.no_prefix_raw().range_raw(store, min, max, order)
155 }
156
157 pub fn keys_raw<'c>(
158 &self,
159 store: &'c dyn Storage,
160 min: Option<Bound<'a, IK>>,
161 max: Option<Bound<'a, IK>>,
162 order: Order,
163 ) -> Box<dyn Iterator<Item = Vec<u8>> + 'c> {
164 self.no_prefix_raw().keys_raw(store, min, max, order)
165 }
166}
167
168#[cfg(feature = "iterator")]
169impl<'a, IK, T, PK> UniqueIndex<'a, IK, T, PK>
170where
171 PK: PrimaryKey<'a> + KeyDeserialize,
172 T: Serialize + DeserializeOwned + Clone,
173 IK: PrimaryKey<'a>,
174{
175 pub fn prefix_range<'c>(
182 &self,
183 store: &'c dyn Storage,
184 min: Option<PrefixBound<'a, IK::Prefix>>,
185 max: Option<PrefixBound<'a, IK::Prefix>>,
186 order: Order,
187 ) -> Box<dyn Iterator<Item = StdResult<(PK::Output, T)>> + 'c>
188 where
189 T: 'c,
190 'a: 'c,
191 IK: 'c,
192 PK: 'c,
193 PK::Output: 'static,
194 {
195 let mapped = namespaced_prefix_range(store, self.idx_namespace, min, max, order)
196 .map(deserialize_kv::<PK, T>);
197 Box::new(mapped)
198 }
199
200 pub fn range<'c>(
201 &self,
202 store: &'c dyn Storage,
203 min: Option<Bound<'a, IK>>,
204 max: Option<Bound<'a, IK>>,
205 order: Order,
206 ) -> Box<dyn Iterator<Item = StdResult<(PK::Output, T)>> + 'c>
207 where
208 T: 'c,
209 PK::Output: 'static,
210 {
211 self.no_prefix().range(store, min, max, order)
212 }
213
214 pub fn keys<'c>(
215 &self,
216 store: &'c dyn Storage,
217 min: Option<Bound<'a, IK>>,
218 max: Option<Bound<'a, IK>>,
219 order: Order,
220 ) -> Box<dyn Iterator<Item = StdResult<PK::Output>> + 'c>
221 where
222 T: 'c,
223 PK::Output: 'static,
224 {
225 self.no_prefix().keys(store, min, max, order)
226 }
227
228 pub fn prefix(&self, p: IK::Prefix) -> IndexPrefix<PK, T, IK::Suffix> {
229 IndexPrefix::with_deserialization_functions(
230 self.idx_namespace,
231 &p.prefix(),
232 &[],
233 |_, _, kv| deserialize_unique_kv::<PK, _>(kv),
234 |_, _, kv| deserialize_unique_v(kv),
235 )
236 }
237
238 pub fn sub_prefix(&self, p: IK::SubPrefix) -> IndexPrefix<PK, T, IK::SuperSuffix> {
239 IndexPrefix::with_deserialization_functions(
240 self.idx_namespace,
241 &p.prefix(),
242 &[],
243 |_, _, kv| deserialize_unique_kv::<PK, _>(kv),
244 |_, _, kv| deserialize_unique_v(kv),
245 )
246 }
247
248 fn no_prefix(&self) -> IndexPrefix<PK, T, IK> {
249 IndexPrefix::with_deserialization_functions(
250 self.idx_namespace,
251 &[],
252 &[],
253 |_, _, kv| deserialize_unique_kv::<PK, _>(kv),
254 |_, _, kv| deserialize_unique_v(kv),
255 )
256 }
257}