Skip to content

Commit b5274ea

Browse files
committed
(dirty) iteration
1 parent 46141a8 commit b5274ea

File tree

4 files changed

+315
-30
lines changed

4 files changed

+315
-30
lines changed

docs-test-gen/src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ static TEMPLATES: phf::Map<&'static str, &'static str> = phf_map! {
1313
"ibc-packet" => include_str!("../templates/ibc-packet.tpl"),
1414
"storage" => include_str!("../templates/storage.tpl"),
1515
"storey-container-impl" => include_str!("../templates/storey-container-impl.tpl"),
16+
"storey-container-impl-iter" => include_str!("../templates/storey-container-impl-iter.tpl"),
1617
"sylvia-storey-contract" => include_str!("../templates/sylvia/storey_contract.tpl"),
1718
"sylvia-cw-storage-contract" => include_str!("../templates/sylvia/cw_storage_contract.tpl"),
1819
"sylvia-empty" => include_str!("../templates/sylvia/empty.tpl"),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
#![allow(
2+
unexpected_cfgs,
3+
dead_code,
4+
unused_variables,
5+
unused_imports,
6+
clippy::new_without_default
7+
)]
8+
use cosmwasm_schema::cw_serde;
9+
use cosmwasm_std::*;
10+
use storey::containers::{IterableStorable, NonTerminal, Storable};
11+
use storey::storage::{IntoStorage, StorageBranch};
12+
13+
mod users {
14+
use super::*;
15+
16+
use cw_storage_plus::{index_list, IndexedMap, MultiIndex, UniqueIndex};
17+
18+
pub type Handle = String;
19+
20+
#[cw_serde]
21+
pub struct User {
22+
pub handle: String,
23+
pub country: String,
24+
}
25+
26+
pub struct ExampleUsers {
27+
pub alice: User,
28+
pub bob: User,
29+
}
30+
31+
pub fn example_users() -> ExampleUsers {
32+
ExampleUsers {
33+
alice: User {
34+
handle: "alice".to_string(),
35+
country: "Wonderland".to_string(),
36+
},
37+
bob: User {
38+
handle: "bob".to_string(),
39+
country: "USA".to_string(),
40+
},
41+
}
42+
}
43+
44+
#[index_list(User)]
45+
pub struct UserIndexes<'a> {
46+
pub handle_ix: UniqueIndex<'a, Handle, User, Addr>,
47+
pub country_ix: MultiIndex<'a, String, User, Addr>,
48+
}
49+
50+
pub fn user_indexes() -> UserIndexes<'static> {
51+
user_indexes_custom("u", "uh", "uc")
52+
}
53+
54+
pub fn user_indexes_custom(
55+
ns: &'static str,
56+
handle_prefix: &'static str,
57+
country_prefix: &'static str,
58+
) -> UserIndexes<'static> {
59+
UserIndexes {
60+
handle_ix: UniqueIndex::new(|user| user.handle.clone(), handle_prefix),
61+
country_ix: MultiIndex::new(|_pk, user| user.country.clone(), ns, country_prefix),
62+
}
63+
}
64+
}
65+
66+
fn advance_height(env: &mut Env, blocks: u64) {
67+
env.block.height += blocks;
68+
}
69+
70+
pub struct MyMap<V> {
71+
prefix: u8,
72+
phantom: std::marker::PhantomData<V>,
73+
}
74+
75+
impl<V> MyMap<V>
76+
where
77+
V: Storable,
78+
{
79+
pub const fn new(prefix: u8) -> Self {
80+
Self {
81+
prefix,
82+
phantom: std::marker::PhantomData,
83+
}
84+
}
85+
86+
pub fn access<F, S>(&self, storage: F) -> MyMapAccess<V, StorageBranch<S>>
87+
where
88+
(F,): IntoStorage<S>,
89+
{
90+
let storage = (storage,).into_storage();
91+
Self::access_impl(StorageBranch::new(storage, vec![self.prefix]))
92+
}
93+
}
94+
95+
pub struct MyMapAccess<V, S> {
96+
storage: S,
97+
phantom: std::marker::PhantomData<V>,
98+
}
99+
100+
impl<V> Storable for MyMap<V>
101+
where
102+
V: Storable,
103+
{
104+
type Kind = NonTerminal;
105+
type Accessor<S> = MyMapAccess<V, S>;
106+
107+
fn access_impl<S>(storage: S) -> MyMapAccess<V, S> {
108+
MyMapAccess {
109+
storage,
110+
phantom: std::marker::PhantomData,
111+
}
112+
}
113+
}
114+
115+
impl<V, S> MyMapAccess<V, S>
116+
where
117+
V: Storable,
118+
{
119+
pub fn entry(&self, key: u32) -> V::Accessor<StorageBranch<&S>> {
120+
let key = key.to_be_bytes().to_vec();
121+
122+
V::access_impl(StorageBranch::new(&self.storage, key))
123+
}
124+
125+
pub fn entry_mut(&mut self, key: u32) -> V::Accessor<StorageBranch<&mut S>> {
126+
let key = key.to_be_bytes().to_vec();
127+
128+
V::access_impl(StorageBranch::new(&mut self.storage, key))
129+
}
130+
}
131+
132+
use storey::containers::IterableAccessor;
133+
use storey::storage::IterableStorage;
134+
135+
impl<V> IterableStorable for MyMap<V>
136+
where
137+
V: IterableStorable,
138+
<V as IterableStorable>::KeyDecodeError: std::fmt::Display,
139+
{
140+
type Key = (u32, V::Key);
141+
type KeyDecodeError = ();
142+
type Value = V::Value;
143+
type ValueDecodeError = V::ValueDecodeError;
144+
145+
fn decode_key(key: &[u8]) -> Result<Self::Key, ()> {
146+
if key.len() < 4 {
147+
return Err(());
148+
}
149+
150+
let key_arr = key[0..4].try_into().map_err(|_| ())?;
151+
let this_key = u32::from_le_bytes(key_arr);
152+
153+
let rest = V::decode_key(&key[4..]).map_err(|_| ())?;
154+
155+
Ok((this_key, rest))
156+
}
157+
158+
fn decode_value(value: &[u8]) -> Result<Self::Value, Self::ValueDecodeError> {
159+
V::decode_value(value)
160+
}
161+
}
162+
163+
impl<V, S> IterableAccessor for MyMapAccess<V, S>
164+
where
165+
V: IterableStorable,
166+
S: IterableStorage,
167+
{
168+
type Storable = MyMap<V>;
169+
type Storage = S;
170+
171+
fn storage(&self) -> &Self::Storage {
172+
&self.storage
173+
}
174+
}
175+
176+
#[test]
177+
fn doctest() {
178+
#[allow(unused_variables, unused_mut)]
179+
let mut storage = cosmwasm_std::testing::MockStorage::new();
180+
#[allow(unused_mut)]
181+
let mut env = cosmwasm_std::testing::mock_env();
182+
183+
let users = cw_storage_plus::IndexedMap::<Addr, _, _>::new(
184+
"uu",
185+
users::user_indexes_custom("uu", "uuh", "uuc"),
186+
);
187+
188+
let users_data = [
189+
(
190+
Addr::unchecked("aaa"),
191+
users::User {
192+
handle: "alice".to_string(),
193+
country: "Wonderland".to_string(),
194+
},
195+
),
196+
(
197+
Addr::unchecked("bbb"),
198+
users::User {
199+
handle: "bob".to_string(),
200+
country: "USA".to_string(),
201+
},
202+
),
203+
(
204+
Addr::unchecked("ccc"),
205+
users::User {
206+
handle: "carol".to_string(),
207+
country: "UK".to_string(),
208+
},
209+
),
210+
(
211+
Addr::unchecked("ddd"),
212+
users::User {
213+
handle: "dave".to_string(),
214+
country: "USA".to_string(),
215+
},
216+
),
217+
];
218+
219+
for (addr, user) in users_data {
220+
users.save(&mut storage, addr, &user).unwrap();
221+
}
222+
223+
#[rustfmt::skip]
224+
{{code}}
225+
}

docs-test-gen/templates/storey-container-impl.tpl

+1-20
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ fn advance_height(env: &mut Env, blocks: u64) {
6767
env.block.height += blocks;
6868
}
6969

70-
struct MyMap<V> {
70+
pub struct MyMap<V> {
7171
prefix: u8,
7272
phantom: std::marker::PhantomData<V>,
7373
}
@@ -112,25 +112,6 @@ where
112112
}
113113
}
114114

115-
impl<V> IterableStorable for MyMap<V>
116-
where
117-
V: IterableStorable,
118-
<V as IterableStorable>::KeyDecodeError: std::fmt::Display,
119-
{
120-
type Key = (u32, V::Key);
121-
type KeyDecodeError = ();
122-
type Value = V::Value;
123-
type ValueDecodeError = V::ValueDecodeError;
124-
125-
fn decode_key(key: &[u8]) -> Result<Self::Key, ()> {
126-
todo!()
127-
}
128-
129-
fn decode_value(value: &[u8]) -> Result<Self::Value, Self::ValueDecodeError> {
130-
V::decode_value(value)
131-
}
132-
}
133-
134115
impl<V, S> MyMapAccess<V, S>
135116
where
136117
V: Storable,

0 commit comments

Comments
 (0)