Skip to content

Commit

Permalink
feat: Added BorshSchema impl for store::TreeMap<K, V, H> and `Uno…
Browse files Browse the repository at this point in the history
…rderedSet<T, H>` (#1213)
  • Loading branch information
dj8yfo authored Jul 4, 2024
1 parent 23f0545 commit 62875e1
Show file tree
Hide file tree
Showing 4 changed files with 295 additions and 10 deletions.
36 changes: 31 additions & 5 deletions near-sdk/src/store/tree_map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,26 @@ fn expect<T>(val: Option<T>) -> T {
/// - `min`/`max`: O(log(N))
/// - `above`/`below`: O(log(N))
/// - `range` of K elements: O(Klog(N))
#[derive(BorshDeserialize, BorshSerialize)]
#[near(inside_nearsdk)]
pub struct TreeMap<K, V, H = Sha256>
where
K: BorshSerialize + Ord,
V: BorshSerialize,
H: ToKey,
{
// ser/de is independent of `K`, `V`, `H` ser/de, `BorshSerialize`/`BorshDeserialize` bounds removed
#[borsh(bound(serialize = "", deserialize = ""))]
// ser/de is independent of `K`, `V`, `H` ser/de, `BorshSerialize`/`BorshDeserialize`/`BorshSchema` bounds removed
#[cfg_attr(not(feature = "abi"), borsh(bound(serialize = "", deserialize = "")))]
#[cfg_attr(
feature = "abi",
borsh(bound(serialize = "", deserialize = ""), schema(params = ""))
)]
values: LookupMap<K, V, H>,
// ser/de is independent of `K` ser/de, `BorshSerialize`/`BorshDeserialize` bounds removed
#[borsh(bound(serialize = "", deserialize = ""))]
// ser/de is independent of `K` ser/de, `BorshSerialize`/`BorshDeserialize`/`BorshSchema` bounds removed
#[cfg_attr(not(feature = "abi"), borsh(bound(serialize = "", deserialize = "")))]
#[cfg_attr(
feature = "abi",
borsh(bound(serialize = "", deserialize = ""), schema(params = ""))
)]
tree: Tree<K>,
}

Expand Down Expand Up @@ -2129,4 +2137,22 @@ mod tests {
swap_set(&mut map);
assert_eq!(map.tree.root, Some(FreeListIndex(0)));
}

#[cfg(feature = "abi")]
#[test]
fn test_borsh_schema() {
#[derive(
borsh::BorshSerialize, borsh::BorshDeserialize, PartialEq, Eq, PartialOrd, Ord,
)]
struct NoSchemaStruct;

assert_eq!(
"TreeMap".to_string(),
<TreeMap<NoSchemaStruct, NoSchemaStruct> as borsh::BorshSchema>::declaration()
);
let mut defs = Default::default();
<TreeMap<NoSchemaStruct, NoSchemaStruct> as borsh::BorshSchema>::add_definitions_recursively(&mut defs);

insta::assert_snapshot!(format!("{:#?}", defs));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
---
source: near-sdk/src/store/tree_map/mod.rs
expression: "format!(\"{:#?}\", defs)"
---
{
"()": Primitive(
0,
),
"FreeList": Struct {
fields: NamedFields(
[
(
"first_free",
"Option<FreeListIndex>",
),
(
"occupied_count",
"u32",
),
(
"elements",
"Vector",
),
],
),
},
"FreeListIndex": Struct {
fields: UnnamedFields(
[
"u32",
],
),
},
"IndexMap": Struct {
fields: NamedFields(
[
(
"prefix",
"Vec<u8>",
),
],
),
},
"LookupMap": Struct {
fields: NamedFields(
[
(
"prefix",
"Vec<u8>",
),
],
),
},
"Option<FreeListIndex>": Enum {
tag_width: 1,
variants: [
(
0,
"None",
"()",
),
(
1,
"Some",
"FreeListIndex",
),
],
},
"Tree": Struct {
fields: NamedFields(
[
(
"root",
"Option<FreeListIndex>",
),
(
"nodes",
"FreeList",
),
],
),
},
"TreeMap": Struct {
fields: NamedFields(
[
(
"values",
"LookupMap",
),
(
"tree",
"Tree",
),
],
),
},
"Vec<u8>": Sequence {
length_width: 4,
length_range: 0..=4294967295,
elements: "u8",
},
"Vector": Struct {
fields: NamedFields(
[
(
"len",
"u32",
),
(
"values",
"IndexMap",
),
],
),
},
"u32": Primitive(
4,
),
"u8": Primitive(
1,
),
}
39 changes: 34 additions & 5 deletions near-sdk/src/store/unordered_set/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::store::free_list::FreeListIndex;
use crate::store::key::{Sha256, ToKey};
use crate::{env, IntoStorageKey};
use borsh::{BorshDeserialize, BorshSerialize};
use near_sdk_macros::near;
use std::borrow::Borrow;
use std::fmt;

Expand Down Expand Up @@ -87,7 +88,7 @@ use std::fmt;
///
/// [`with_hasher`]: Self::with_hasher
/// [`LookupSet`]: crate::store::LookupSet
#[derive(BorshDeserialize, BorshSerialize)]
#[near(inside_nearsdk)]
#[deprecated(
since = "5.0.0",
note = "Suboptimal iteration performance. See performance considerations doc for details."
Expand All @@ -97,11 +98,19 @@ where
T: BorshSerialize + Ord,
H: ToKey,
{
// ser/de is independent of `T` ser/de, `BorshSerialize`/`BorshDeserialize` bounds removed
#[borsh(bound(serialize = "", deserialize = ""))]
// ser/de is independent of `T` ser/de, `BorshSerialize`/`BorshDeserialize`/`BorshSchema` bounds removed
#[cfg_attr(not(feature = "abi"), borsh(bound(serialize = "", deserialize = "")))]
#[cfg_attr(
feature = "abi",
borsh(bound(serialize = "", deserialize = ""), schema(params = ""))
)]
elements: FreeList<T>,
// ser/de is independent of `T`, `H` ser/de, `BorshSerialize`/`BorshDeserialize` bounds removed
#[borsh(bound(serialize = "", deserialize = ""))]
// ser/de is independent of `T`, `H` ser/de, `BorshSerialize`/`BorshDeserialize`/`BorshSchema` bounds removed
#[cfg_attr(not(feature = "abi"), borsh(bound(serialize = "", deserialize = "")))]
#[cfg_attr(
feature = "abi",
borsh(bound(serialize = "", deserialize = ""), schema(params = ""))
)]
index: LookupMap<T, FreeListIndex, H>,
}

Expand Down Expand Up @@ -949,4 +958,24 @@ mod tests {
// Check the last removed value.
assert_eq!(set.elements.get(FreeListIndex(6)), None);
}

#[cfg(feature = "abi")]
#[test]
fn test_borsh_schema() {
#[derive(
borsh::BorshSerialize, borsh::BorshDeserialize, PartialEq, Eq, PartialOrd, Ord,
)]
struct NoSchemaStruct;

assert_eq!(
"UnorderedSet".to_string(),
<UnorderedSet<NoSchemaStruct> as borsh::BorshSchema>::declaration()
);
let mut defs = Default::default();
<UnorderedSet<NoSchemaStruct> as borsh::BorshSchema>::add_definitions_recursively(
&mut defs,
);

insta::assert_snapshot!(format!("{:#?}", defs));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
---
source: near-sdk/src/store/unordered_set/mod.rs
expression: "format!(\"{:#?}\", defs)"
---
{
"()": Primitive(
0,
),
"FreeList": Struct {
fields: NamedFields(
[
(
"first_free",
"Option<FreeListIndex>",
),
(
"occupied_count",
"u32",
),
(
"elements",
"Vector",
),
],
),
},
"FreeListIndex": Struct {
fields: UnnamedFields(
[
"u32",
],
),
},
"IndexMap": Struct {
fields: NamedFields(
[
(
"prefix",
"Vec<u8>",
),
],
),
},
"LookupMap": Struct {
fields: NamedFields(
[
(
"prefix",
"Vec<u8>",
),
],
),
},
"Option<FreeListIndex>": Enum {
tag_width: 1,
variants: [
(
0,
"None",
"()",
),
(
1,
"Some",
"FreeListIndex",
),
],
},
"UnorderedSet": Struct {
fields: NamedFields(
[
(
"elements",
"FreeList",
),
(
"index",
"LookupMap",
),
],
),
},
"Vec<u8>": Sequence {
length_width: 4,
length_range: 0..=4294967295,
elements: "u8",
},
"Vector": Struct {
fields: NamedFields(
[
(
"len",
"u32",
),
(
"values",
"IndexMap",
),
],
),
},
"u32": Primitive(
4,
),
"u8": Primitive(
1,
),
}

0 comments on commit 62875e1

Please sign in to comment.