abstract_std/objects/pool/
unique_pool_id.rs1use std::fmt::Display;
2
3use cosmwasm_std::StdResult;
4use cw_storage_plus::{IntKey, KeyDeserialize, Prefixer, PrimaryKey};
5use schemars::JsonSchema;
6use serde::{Deserialize, Serialize};
7
8#[derive(
9 Deserialize, Serialize, Clone, Debug, PartialEq, Eq, JsonSchema, PartialOrd, Ord, Copy,
10)]
11#[cfg_attr(not(target_arch = "wasm32"), derive(Hash))]
13pub struct UniquePoolId(u64);
14
15impl UniquePoolId {
16 pub const fn new(id: u64) -> Self {
17 Self(id)
18 }
19 pub fn as_u64(&self) -> u64 {
20 self.0
21 }
22 pub fn increment(&mut self) {
23 self.0 += 1;
24 }
25}
26
27impl From<u64> for UniquePoolId {
28 fn from(id: u64) -> Self {
29 Self::new(id)
30 }
31}
32
33impl Display for UniquePoolId {
34 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35 write!(f, "{}", self.0)
36 }
37}
38
39impl PrimaryKey<'_> for UniquePoolId {
40 type Prefix = ();
41 type SubPrefix = ();
42 type Suffix = Self;
43 type SuperSuffix = Self;
44
45 fn key(&self) -> Vec<cw_storage_plus::Key> {
46 self.0.key()
47 }
48}
49
50impl Prefixer<'_> for UniquePoolId {
51 fn prefix(&self) -> Vec<cw_storage_plus::Key> {
52 self.0.prefix()
53 }
54}
55
56impl KeyDeserialize for UniquePoolId {
57 type Output = Self;
58 const KEY_ELEMS: u16 = 1;
59
60 #[inline(always)]
61 fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
62 Ok(Self(u64::from_vec(value)?))
63 }
64}
65
66impl IntKey for UniquePoolId {
67 type Buf = [u8; std::mem::size_of::<u64>()];
68
69 #[inline]
70 fn to_cw_bytes(&self) -> Self::Buf {
71 self.0.to_be_bytes()
72 }
73
74 #[inline]
75 fn from_cw_bytes(bytes: Self::Buf) -> Self {
76 Self(u64::from_be_bytes(bytes))
77 }
78}
79
80#[cfg(test)]
81mod test {
82 #![allow(clippy::needless_borrows_for_generic_args)]
83 use cosmwasm_std::{testing::mock_dependencies, Addr, Order};
84 use cw_storage_plus::Map;
85
86 use super::*;
87
88 fn mock_key() -> UniquePoolId {
89 UniquePoolId::new(1)
90 }
91
92 fn _mock_keys() -> (UniquePoolId, UniquePoolId, UniquePoolId) {
93 (
94 UniquePoolId::new(1),
95 UniquePoolId::new(2),
96 UniquePoolId::new(3),
97 )
98 }
99
100 #[coverage_helper::test]
101 fn storage_key_works() {
102 let mut deps = mock_dependencies();
103 let key = mock_key();
104 let map: Map<UniquePoolId, u64> = Map::new("map");
105
106 map.save(deps.as_mut().storage, key, &42069).unwrap();
107
108 assert_eq!(map.load(deps.as_ref().storage, key).unwrap(), 42069);
109
110 let items = map
111 .range(deps.as_ref().storage, None, None, Order::Ascending)
112 .map(|item| item.unwrap())
113 .collect::<Vec<_>>();
114
115 assert_eq!(items.len(), 1);
116 assert_eq!(items[0], (key, 42069));
117 }
118
119 #[coverage_helper::test]
120 fn composite_key_works() {
121 let mut deps = mock_dependencies();
122 let key = mock_key();
123 let map: Map<(UniquePoolId, Addr), u64> = Map::new("map");
124
125 map.save(
126 deps.as_mut().storage,
127 (key, Addr::unchecked("larry")),
128 &42069,
129 )
130 .unwrap();
131
132 map.save(
133 deps.as_mut().storage,
134 (key, Addr::unchecked("jake")),
135 &69420,
136 )
137 .unwrap();
138
139 let items = map
140 .prefix(key)
141 .range(deps.as_ref().storage, None, None, Order::Ascending)
142 .map(|item| item.unwrap())
143 .collect::<Vec<_>>();
144
145 assert_eq!(items.len(), 2);
146 assert_eq!(items[0], (Addr::unchecked("jake"), 69420));
147 assert_eq!(items[1], (Addr::unchecked("larry"), 42069));
148 }
149
150 #[coverage_helper::test]
151 fn naked_64key_works() {
152 let k: UniquePoolId = 4242u64.into();
153 let path = k.key();
154 assert_eq!(1, path.len());
155 assert_eq!(4242u64.to_cw_bytes(), path[0].as_ref());
156 }
157}