The goal here is to implement a basic binary tree with values only on leaves, with `depth`, `mirror`, and `in_order` (traversal) operations.

I have not used Rust before.

Some particular questions I have:

  * In a few places, I'm defining methods by passing `self` by reference and then matching on its derefenced form. I then have to borrow the fields with `ref` in the destructuring. Is this the intended form?
  * Is `into_in_order` using `Vec` properly/optimally? (I tried to use just `lv.extend(&mut rv)` but got an error that that particular method was still under churn and I should wait for "the dust to settle.")
  * Am I using `Box`es correctly? When should I use `Box`es vs. `* const`s?
  * Why do `(*r).mirror()` and `r.mirror()` do the same thing? I would have expected the latter to throw because `Box`es don't have a `mirror` method.
  * Is there a less verbose alternative to the `Branch(Box::new(Branch(…)))` syntax?

<!-- x -->

    #[derive(Debug, PartialEq, Clone)]
    enum BTree<T> {
        Leaf(T),
        Branch(Box<BTree<T>>, Box<BTree<T>>),
    }
    
    impl <T> BTree<T> {
    
        fn depth(&self) -> i32 {
            match *self {
                BTree::Leaf(_) => 1,
                BTree::Branch(ref l, ref r) =>
                    std::cmp::max(l.depth(), r.depth()) + 1,
            }
        }
    
        fn into_in_order(self) -> Vec<T> {
            match self {
                BTree::Leaf(val) => vec!(val),
                BTree::Branch(l, r) => {
                    let mut lv = l.into_in_order();
                    let rv = r.into_in_order();
                    lv.extend(rv.into_iter());
                    lv
                }
            }
        }
    
    }
    
    impl <T : Clone> BTree<T> {
    
        fn mirror(&self) -> BTree<T> {
            match *self {
                BTree::Leaf(_) => (*self).clone(),
                BTree::Branch(ref l, ref r) =>
                    BTree::Branch(Box::new((*r).mirror()), Box::new((*l).mirror())),
                    //
                    // why does this work?
                    // BTree::Branch(Box::new(r.mirror()), Box::new(l.mirror())),
            }
        }
    
    }
    
    #[test]
    #[allow(unused_variables)]
    fn test_btree_creation() {
        use BTree::*;
    
        let leaf: BTree<i32> = Leaf(10);
        let branch: BTree<i32> = Branch(Box::new(Leaf(15)), Box::new(Leaf(20)));
        let tree: BTree<i32> = Branch(Box::new(branch.clone()), Box::new(Leaf(30)));
    
        assert_eq!(branch, branch.clone());
    }
    
    #[test]
    fn test_btree_depth() {
        use BTree::*;
    
        assert_eq!(Leaf(10).depth(), 1);
    
        let branch: BTree<i32> = Branch(Box::new(Leaf(15)), Box::new(Leaf(20)));
        assert_eq!(branch.depth(), 2);
    
        let tree: BTree<i32> = Branch(Box::new(branch.clone()), Box::new(Leaf(30)));
        assert_eq!(tree.depth(), 3);
    
        let other_tree: BTree<i32> = Branch(
            Box::new(branch.clone()), Box::new(branch.clone()));
        assert_eq!(other_tree.depth(), 3);
    }
    
    #[test]
    fn test_btree_mirror() {
        use BTree::*;
    
        assert_eq!(Leaf(10).mirror(), Leaf(10));
    
        assert_eq!(
            Branch(Box::new(Leaf(10)), Box::new(Leaf(20))).mirror(),
            Branch(Box::new(Leaf(20)), Box::new(Leaf(10))));
    
        assert_eq!(
            Branch(
                Box::new(Leaf(10)),
                Box::new(Branch(Box::new(Leaf(20)), Box::new(Leaf(30))))
            ).mirror(),
            Branch(
                Box::new(Branch(Box::new(Leaf(30)),
                Box::new(Leaf(20)))), Box::new(Leaf(10))));
    }
    
    #[test]
    fn test_btree_in_order() {
        use BTree::*;
    
        assert_eq!(Leaf(10).into_in_order(), vec!(10));
    
        assert_eq!(Branch(Box::new(Leaf(10)), Box::new(Leaf(20))).into_in_order(),
            vec!(10, 20));
    
        assert_eq!(
            Branch(
                Box::new(Leaf(10)),
                Box::new(Branch(Box::new(Leaf(20)), Box::new(Leaf(30))))
            ).into_in_order(),
            vec!(10, 20, 30));
    }

I also have the following macro definitions (not all used above):

    macro_rules! assert_eq {
        ($actual:expr, $expected:expr) => (
            if $expected != $actual {
                panic!("expected {:?}, but got {:?}", $expected, $actual);
            }
        )
    }
    macro_rules! assert_neq {
        ($actual: expr, $expected_not: expr) => (
            if $expected_not == $actual {
                panic!("expected {:?} not to equal {:?}", $expected_not, $actual);
            }
        )
    }
    macro_rules! assert_approx {
        ($actual: expr, $expected: expr) => {
            if ($expected - $actual).abs() > 1e-3 {
                panic!("expected {:?} or similar, but got {:?}", $expected, $actual);
            }
        }
    }