1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
// Tells the compiler not to throw warnings for unused code #[allow(dead_code)] // Use statements // // Standard library use std::*; // Gives access to hash utilities use hash_util::*; /* * * Tree: * - This file contains enums, structs, and impls for creating binary trees, and * and methods for accessing their information. * */ /* Enum for the tree used for allowing multiple classifications of trees: * * - An empty tree that contains only a hash * - A tree leaf that contains a hash and a value * - A tree node ( or root node ) that contains a hash and left and right children * */ #[derive(Clone)] pub enum Tree<T> { // Empty tree definition Empty { // Empty trees only contain a hash hash: String }, // Leaf definition Leaf { // Leaves act as a node with a hash and value but no children hash: String, value: T }, // Node ( tree definiton ) // The node functions as the normal tree definition as it contains a hash field // and two children. // // Note: Boxes are used for allocating memory on the heap for the left and right tree // values. Node { // Nodes have a hash and left and right children hash: String, left: Box<Tree<T>>, right: Box<Tree<T>> } } // Tree impl impl<T: fmt::Display> Tree<T> { // Empty tree constructor #[allow(dead_code)] pub fn empty( ) -> Self { // Returns an empty tree with the given hash Tree::Empty{ hash: ::hash_util::empty_hash() } } // Leaf node constructor #[allow(dead_code)] pub fn leaf( value: T ) -> Tree<T> { // Creates the hash given the leaf's value, create_leaf_hash() takes in // a reference to the value so we pass in value.as_ref() let leaf_hash = create_leaf_hash( &value ); // Returns a tree leaf with the given hash and value Tree::Leaf { hash: leaf_hash, value: value } } // Tree node constructor #[allow(dead_code)] pub fn node( left: Tree<T>, right: Tree<T> ) -> Tree<T> { // Creates the node hash using the children's hashes. // Passes in the reference to the left and write hashes by // using unwrap() let node_hash = create_node_hash( left.hash(), right.hash() ); // Returns a tree node with the given hash and // allocates memory for the left and right children Tree::Node { hash: node_hash, left: Box::new(left), right: Box::new(right) } } // Retrieve the hash of a given tree #[allow(dead_code)] pub fn hash( &self ) -> &String { // Includes tree use self::*; // Match self to enum type match *self { // ref allows us to reference a field of the enum // If it's an empty tree Tree::Empty { ref hash } => hash, // If it's a tree node Tree::Node { ref hash, .. } => hash, // If it's a leaf node Tree::Leaf { ref hash, .. } => hash } } }