1 个不稳定版本
0.1.2 | 2022 年 5 月 20 日 |
---|
#21 in #accessor
53KB
1.5K SLoC
存储额外功能
为访问 cw-storage-plus
和 cosmwasm-storage
提供附加功能实现
Cow
在 cw-storage-plus
中实现存储访问器的 Cow 实现,以提供命名空间的拥有字符串变体,这对于通过 format!
宏动态构建访问器非常有用。
还实现了新的有用存储访问器,例如 ConditionalMultiIndex
和 CustomDeseMultiIndex
每个结构体都将有权访问 new_owned
和 new_ref
常量构造函数。
ItemCow
类似于来自 cw-storage-plus
的 Item
,但在 Cow
中。
let item: ItemCow<Addr> = ItemCow::new_owned(String::from("g"));
const ITEM: ItemCow<Addr> = ItemCow::new_ref("g");
MapCow
类似于来自 cw-storage-plus
的 Map
,但在 Cow
中。
let addr_owne: MapCow<&Addr, u64> = MapCow::new_owned(String::from("g"));
const ADDR_REF: MapCow<&Addr, u64> = MapCow::new_ref("g");
IndexMapCow
类似于来自 cw-storage-plus
的 IndexedMap
,但在 Cow
中。 Index
结构可以从正常的 Index
特性构建,如 MultiIndex
和 UniqueIndex
。
MultiIndexCow
类似于来自 cw-storage-plus
的 MultiIndex
,但在 Cow
中。也可用于正常的 IndexedMap
。
UniqueIndexCow
类似于来自 cw-storage-plus
的 UniqueIndex
,但在 Cow
中。也可用于正常的 IndexedMap
。
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
struct ToIndex {
id: u64,
count: u64,
address: Addr,
}
#[derive(Clone)]
struct ToIndexList<'a> {
count: MultiIndexCow<'a, (U64Key, Vec<u8>), ToIndex>,
address: UniqueIndexCow<'a, Addr, ToIndex>,
}
const TO: IndexedMapCow<U64Key, ToIndex, ToIndexList> = IndexedMapCow::new_ref(
"primary",
ToIndexList {
count: MultiIndexCow::new_ref("primary", "primary_count", |e, k| {
(e.count.into(), k)
}),
address: UniqueIndexCow::new_ref("primary_address", |e| e.address.clone()),
},
);
let to: IndexedMapCow<U64Key, ToIndex, ToIndexList> = IndexedMapCow::new_owned(
"primary".to_string(),
ToIndexList {
count: MultiIndexCow::new_owned(
"primary".to_string(),
"primary_count".to_string(),
|e, k| (e.count.into(), k),
),
address: UniqueIndexCow::new_owned("primary_address".to_string(), |e| {
e.address.clone()
}),
},
);
CustomDeseMultiIndex
具有可自定义索引的 MultiIndexCow
,用于 pk 反序列化函数。也可用于正常的 IndexedMap
。
使用 deserialize_multi_kv_custom_pk
辅助函数将旧 kv 映射到新 kv,也适用于完全自定义的情况。
使用 None
以正常 MultiIndexCow
操作。
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
struct Test {
id: u64,
val: Uint128,
}
struct TestIndexes<'a> {
val: CustomDeseMultiIndex<'a, (U128Key, Vec<u8>), Test>,
}
fn idm<'a>() -> IndexedMap<'a, U64Key, Test, TestIndexes<'a>> {
IndexedMap::new(
"test",
TestIndexes {
val: CustomDeseMultiIndex::new_ref(
|t, _| {
(
t.val.u128().into(),
U64Key::new(u64::max_value() - t.id).joined_key(),
)
},
Some(|s, pk, kv| {
deserialize_multi_kv_custom_pk(s, pk, kv, |old_kv| {
U64Key::new(
u64::max_value()
- u64::from_be_bytes(old_kv.as_slice().try_into().unwrap()),
)
.joined_key()
})
}),
"test",
"test__val",
),
},
)
}
ConditionalMultiIndex
具有额外条件的 CustomDeseMultiIndex
,用于从原始索引映射中保存/删除。对于减少复合键复杂性非常有用。也可用于正常的 IndexedMap
。
cond_fn
必须是常量,否则可能会出现意外的行为。
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
struct Test {
id: u64,
val: Uint128,
}
struct TestIndexes<'a> {
val: ConditionalMultiIndex<'a, (U128Key, Vec<u8>), Test>,
}
fn idm<'a>() -> IndexedMap<'a, U64Key, Test, TestIndexes<'a>> {
IndexedMap::new(
"test",
TestIndexes {
val: ConditionalMultiIndex::new_ref(
|t, k| (t.val.u128().into(), k),
// only add to val if t.val > 100
|t| t.val.u128() > 100,
None,
"test",
"test__val",
),
},
)
}
```d
依赖关系
~3–4.5MB
~100K SLoC