1use cosmwasm_std::{Order, StdError, StdResult, Storage};
2use cw_storage_plus::{Bound, IndexList, IndexedMap, KeyDeserialize, Map, PrimaryKey};
3use serde::{de::DeserializeOwned, ser::Serialize};
4
5pub const DEFAULT_LIMIT: u32 = 10;
6pub const MAX_LIMIT: u32 = 30;
7
8pub fn collect<'a, D, T, R, E, F>(
13 iter: Box<dyn Iterator<Item = StdResult<(D, T)>> + 'a>,
14 limit: Option<u32>,
15 parse_fn: F,
16) -> Result<Vec<R>, E>
17where
18 F: Fn(D, T) -> Result<R, E>,
19 E: From<StdError>,
20{
21 let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize;
22 iter.take(limit)
23 .map(|item| {
24 let (k, v) = item?;
25 parse_fn(k, v)
26 })
27 .collect()
28}
29
30pub fn paginate_map<'a, K, T, R, E, F>(
34 map: &Map<K, T>,
35 store: &dyn Storage,
36 start: Option<Bound<'a, K>>,
37 limit: Option<u32>,
38 parse_fn: F,
39) -> Result<Vec<R>, E>
40where
41 K: PrimaryKey<'a> + KeyDeserialize,
42 K::Output: 'static,
43 T: Serialize + DeserializeOwned,
44 F: Fn(K::Output, T) -> Result<R, E>,
45 E: From<StdError>,
46{
47 let iter = map.range(store, start, None, Order::Ascending);
48 collect(iter, limit, parse_fn)
49}
50
51pub fn paginate_map_prefix<'a, K, T, R, E, F>(
55 map: &Map<K, T>,
56 store: &dyn Storage,
57 prefix: K::Prefix,
58 start: Option<Bound<'a, K::Suffix>>,
59 limit: Option<u32>,
60 parse_fn: F,
61) -> Result<Vec<R>, E>
62where
63 K: PrimaryKey<'a>,
64 K::Suffix: PrimaryKey<'a> + KeyDeserialize,
65 <K::Suffix as KeyDeserialize>::Output: 'static,
66 T: Serialize + DeserializeOwned,
67 F: Fn(<K::Suffix as KeyDeserialize>::Output, T) -> Result<R, E>,
68 E: From<StdError>,
69{
70 let iter = map.prefix(prefix).range(store, start, None, Order::Ascending);
71 collect(iter, limit, parse_fn)
72}
73
74pub fn paginate_indexed_map<'a, K, T, I, R, E, F>(
78 map: &IndexedMap<K, T, I>,
79 store: &dyn Storage,
80 start: Option<Bound<'a, K>>,
81 limit: Option<u32>,
82 parse_fn: F,
83) -> Result<Vec<R>, E>
84where
85 K: PrimaryKey<'a> + KeyDeserialize,
86 K::Output: 'static,
87 T: Serialize + DeserializeOwned + Clone,
88 I: IndexList<T>,
89 F: Fn(K::Output, T) -> Result<R, E>,
90 E: From<StdError>,
91{
92 let iter = map.range(store, start, None, Order::Ascending);
93 collect(iter, limit, parse_fn)
94}
95
96