Skip to content

Commit

Permalink
Implement Debug for collection types
Browse files Browse the repository at this point in the history
  • Loading branch information
itegulov committed Nov 29, 2021
1 parent 7210661 commit eee73c0
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 69 deletions.
Binary file modified examples/non-fungible-token/res/non_fungible_token.wasm
Binary file not shown.
86 changes: 52 additions & 34 deletions near-sdk/src/collections/legacy_tree_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,36 @@ where
}
}

#[cfg(feature = "expensive-debug")]
impl<K> std::fmt::Debug for Node<K>
where
K: std::fmt::Debug + Ord + Clone + BorshSerialize + BorshDeserialize,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Node")
.field("id", &self.id)
.field("key", &self.key)
.field("lft", &self.lft)
.field("rgt", &self.rgt)
.field("ht", &self.ht)
.finish()
}
}

#[cfg(feature = "expensive-debug")]
impl<K, V> std::fmt::Debug for LegacyTreeMap<K, V>
where
K: std::fmt::Debug + Ord + Clone + BorshSerialize + BorshDeserialize,
V: std::fmt::Debug + BorshSerialize + BorshDeserialize,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("LegacyTreeMap")
.field("root", &self.root)
.field("tree", &self.tree.iter().collect::<Vec<Node<K>>>())
.finish()
}
}

impl<'a, K, V> IntoIterator for &'a LegacyTreeMap<K, V>
where
K: Ord + Clone + BorshSerialize + BorshDeserialize,
Expand Down Expand Up @@ -682,12 +712,10 @@ mod tests {
use crate::test_utils::{next_trie_id, test_env};

extern crate rand;
use self::rand::RngCore;
use self::rand::{Rng, RngCore, SeedableRng};
use quickcheck::QuickCheck;
use std::collections::BTreeMap;
use std::collections::HashSet;
use std::fmt::Formatter;
use std::fmt::{Debug, Result};

/// Return height of the tree - number of nodes on the longest path starting from the root node.
fn height<K, V>(tree: &LegacyTreeMap<K, V>) -> u64
Expand Down Expand Up @@ -724,35 +752,6 @@ mod tests {
h.ceil() as u64
}

impl<K> Debug for Node<K>
where
K: Ord + Clone + Debug + BorshSerialize + BorshDeserialize,
{
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
f.debug_struct("Node")
.field("id", &self.id)
.field("key", &self.key)
.field("lft", &self.lft)
.field("rgt", &self.rgt)
.field("ht", &self.ht)
.finish()
}
}

impl<K, V> Debug for LegacyTreeMap<K, V>
where
K: Ord + Clone + Debug + BorshSerialize + BorshDeserialize,
V: Debug + BorshSerialize + BorshDeserialize,
{
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
f.debug_struct("TreeMap")
.field("root", &self.root)
.field("tree", &self.tree.iter().collect::<Vec<Node<K>>>())
.field("val", &self.val.iter().collect::<Vec<(K, V)>>())
.finish()
}
}

#[test]
fn test_empty() {
let map: LegacyTreeMap<u8, u8> = LegacyTreeMap::new(b't');
Expand Down Expand Up @@ -1610,8 +1609,8 @@ mod tests {

fn is_balanced<K, V>(map: &LegacyTreeMap<K, V>, root: u64) -> bool
where
K: Debug + Ord + Clone + BorshSerialize + BorshDeserialize,
V: Debug + BorshSerialize + BorshDeserialize,
K: std::fmt::Debug + Ord + Clone + BorshSerialize + BorshDeserialize,
V: std::fmt::Debug + BorshSerialize + BorshDeserialize,
{
let node = map.node(root).unwrap();
let balance = map.get_balance(&node);
Expand Down Expand Up @@ -1705,4 +1704,23 @@ mod tests {

QuickCheck::new().tests(300).quickcheck(prop as Prop);
}

#[test]
#[cfg(feature = "expensive-debug")]
fn test_debug() {
let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(4);
let mut map = LegacyTreeMap::new(b"m");
let mut baseline = vec![];
for _ in 0..10 {
let key = rng.gen::<u64>();
let value = rng.gen::<u64>();
baseline.push((key, value));
map.insert(&key, &value);
}

assert_eq!(
format!("{:?}", map),
format!("LegacyTreeMap {{ root: {:?}, tree: {:?} }}", map.root, map.tree)
);
}
}
20 changes: 19 additions & 1 deletion near-sdk/src/collections/lookup_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const ERR_VALUE_DESERIALIZATION: &str = "Cannot deserialize value with Borsh";
const ERR_VALUE_SERIALIZATION: &str = "Cannot serialize value with Borsh";

/// An non-iterable implementation of a map that stores its content directly on the trie.
#[derive(BorshSerialize, BorshDeserialize)]
#[derive(BorshSerialize, BorshDeserialize, Debug)]
pub struct LookupMap<K, V> {
key_prefix: Vec<u8>,
#[borsh_skip]
Expand Down Expand Up @@ -284,4 +284,22 @@ mod tests {
assert_eq!(map.get(&key).unwrap(), value);
}
}

#[test]
fn test_debug() {
let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(4);
let mut map = LookupMap::new(b"m");
let mut baseline = vec![];
for _ in 0..10 {
let key = rng.gen::<u64>();
let value = rng.gen::<u64>();
baseline.push((key, value));
map.insert(&key, &value);
}

assert_eq!(
format!("{:?}", map),
format!("LookupMap {{ key_prefix: {:?}, el: PhantomData }}", map.key_prefix)
);
}
}
19 changes: 18 additions & 1 deletion near-sdk/src/collections/lookup_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{env, IntoStorageKey};
const ERR_ELEMENT_SERIALIZATION: &str = "Cannot serialize element with Borsh";

/// An non-iterable implementation of a set that stores its content directly on the trie.
#[derive(BorshSerialize, BorshDeserialize)]
#[derive(BorshSerialize, BorshDeserialize, Debug)]
pub struct LookupSet<T> {
element_prefix: Vec<u8>,
#[borsh_skip]
Expand Down Expand Up @@ -204,4 +204,21 @@ mod tests {
assert!(set.contains(&key));
}
}

#[test]
fn test_debug() {
let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(4);
let mut set = LookupSet::new(b"m");
let mut baseline = vec![];
for _ in 0..10 {
let value = rng.gen::<u64>();
baseline.push(value);
set.insert(&value);
}

assert_eq!(
format!("{:?}", set),
format!("LookupSet {{ element_prefix: {:?}, el: PhantomData }}", set.element_prefix)
);
}
}
85 changes: 52 additions & 33 deletions near-sdk/src/collections/tree_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,36 @@ where
}
}

#[cfg(feature = "expensive-debug")]
impl<K, V> std::fmt::Debug for TreeMap<K, V>
where
K: std::fmt::Debug + Ord + Clone + BorshSerialize + BorshDeserialize,
V: std::fmt::Debug + BorshSerialize + BorshDeserialize,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("TreeMap")
.field("root", &self.root)
.field("tree", &self.tree.iter().collect::<Vec<Node<K>>>())
.finish()
}
}

#[cfg(feature = "expensive-debug")]
impl<K> std::fmt::Debug for Node<K>
where
K: std::fmt::Debug + Ord + Clone + BorshSerialize + BorshDeserialize,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Node")
.field("id", &self.id)
.field("key", &self.key)
.field("lft", &self.lft)
.field("rgt", &self.rgt)
.field("ht", &self.ht)
.finish()
}
}

impl<'a, K, V> IntoIterator for &'a TreeMap<K, V>
where
K: Ord + Clone + BorshSerialize + BorshDeserialize,
Expand Down Expand Up @@ -729,12 +759,10 @@ mod tests {
use crate::test_utils::{next_trie_id, test_env};

extern crate rand;
use self::rand::RngCore;
use self::rand::{Rng, RngCore, SeedableRng};
use quickcheck::QuickCheck;
use std::collections::BTreeMap;
use std::collections::HashSet;
use std::fmt::Formatter;
use std::fmt::{Debug, Result};

/// Return height of the tree - number of nodes on the longest path starting from the root node.
fn height<K, V>(tree: &TreeMap<K, V>) -> u64
Expand Down Expand Up @@ -771,34 +799,6 @@ mod tests {
h.ceil() as u64
}

impl<K> Debug for Node<K>
where
K: Ord + Clone + Debug + BorshSerialize + BorshDeserialize,
{
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
f.debug_struct("Node")
.field("id", &self.id)
.field("key", &self.key)
.field("lft", &self.lft)
.field("rgt", &self.rgt)
.field("ht", &self.ht)
.finish()
}
}

impl<K, V> Debug for TreeMap<K, V>
where
K: Ord + Clone + Debug + BorshSerialize + BorshDeserialize,
V: Debug + BorshSerialize + BorshDeserialize,
{
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
f.debug_struct("TreeMap")
.field("root", &self.root)
.field("tree", &self.tree.iter().collect::<Vec<Node<K>>>())
.finish()
}
}

#[test]
fn test_empty() {
let map: TreeMap<u8, u8> = TreeMap::new(b't');
Expand Down Expand Up @@ -1682,8 +1682,8 @@ mod tests {

fn is_balanced<K, V>(map: &TreeMap<K, V>, root: u64) -> bool
where
K: Debug + Ord + Clone + BorshSerialize + BorshDeserialize,
V: Debug + BorshSerialize + BorshDeserialize,
K: std::fmt::Debug + Ord + Clone + BorshSerialize + BorshDeserialize,
V: std::fmt::Debug + BorshSerialize + BorshDeserialize,
{
let node = map.node(root).unwrap();
let balance = map.get_balance(&node);
Expand Down Expand Up @@ -1777,4 +1777,23 @@ mod tests {

QuickCheck::new().tests(300).quickcheck(prop as Prop);
}

#[test]
#[cfg(feature = "expensive-debug")]
fn test_debug() {
let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(4);
let mut map = TreeMap::new(b"m");
let mut baseline = vec![];
for _ in 0..10 {
let key = rng.gen::<u64>();
let value = rng.gen::<u64>();
baseline.push((key, value));
map.insert(&key, &value);
}

assert_eq!(
format!("{:?}", map),
format!("TreeMap {{ root: {:?}, tree: {:?} }}", map.root, map.tree)
);
}
}
27 changes: 27 additions & 0 deletions near-sdk/src/collections/unordered_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,17 @@ where
}
}

#[cfg(feature = "expensive-debug")]
impl<K, V> std::fmt::Debug for UnorderedMap<K, V>
where
K: std::fmt::Debug + BorshSerialize + BorshDeserialize,
V: std::fmt::Debug + BorshSerialize + BorshDeserialize,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.to_vec().fmt(f)
}
}

#[cfg(not(target_arch = "wasm32"))]
#[cfg(test)]
mod tests {
Expand Down Expand Up @@ -442,4 +453,20 @@ mod tests {
let actual: HashMap<u64, u64> = map.iter().collect();
assert_eq!(actual, key_to_value);
}

#[test]
#[cfg(feature = "expensive-debug")]
fn test_debug() {
let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(4);
let mut map = UnorderedMap::new(b"m");
let mut baseline = vec![];
for _ in 0..10 {
let key = rng.gen::<u64>();
let value = rng.gen::<u64>();
baseline.push((key, value));
map.insert(&key, &value);
}

assert_eq!(format!("{:#?}", map), format!("{:#?}", baseline));
}
}
25 changes: 25 additions & 0 deletions near-sdk/src/collections/unordered_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,16 @@ where
}
}

#[cfg(feature = "expensive-debug")]
impl<T> std::fmt::Debug for UnorderedSet<T>
where
T: std::fmt::Debug + BorshSerialize + BorshDeserialize,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.to_vec().fmt(f)
}
}

#[cfg(not(target_arch = "wasm32"))]
#[cfg(test)]
mod tests {
Expand Down Expand Up @@ -330,4 +340,19 @@ mod tests {
let actual: HashSet<u64> = set.iter().collect();
assert_eq!(actual, keys);
}

#[test]
#[cfg(feature = "expensive-debug")]
fn test_debug() {
let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(4);
let mut set = UnorderedSet::new(b"m");
let mut baseline = vec![];
for _ in 0..10 {
let value = rng.gen::<u64>();
baseline.push(value);
set.insert(&value);
}

assert_eq!(format!("{:#?}", set), format!("{:#?}", baseline));
}
}
10 changes: 10 additions & 0 deletions near-sdk/src/store/lazy_option/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,13 @@ where
Self::get_mut(self)
}
}

#[cfg(feature = "expensive-debug")]
impl<T> std::fmt::Debug for LazyOption<T>
where
T: std::fmt::Debug + BorshSerialize + BorshDeserialize,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.get().fmt(f)
}
}
Loading

0 comments on commit eee73c0

Please sign in to comment.