use std::rc::Rc;
use std::fmt::Display;

enum Node<T> {
    Nil,
    Value(T, Rc<Node<T>>),
}

fn build_chain_str() -> Node<String> {
    let mut chain = Node::<String>::Nil;
    for &n in &["Tom", "Jerry", "Mike"] {
        let node = Node::<String>::Value(n.into(), Rc::new(chain));
        chain = node;
    }
    chain
}

fn build_chain_usize() -> Node<usize> {
    let mut chain = Node::<usize>::Nil;
    for &n in &[1, 2, 3, 4, 5] {
        let node = Node::<usize>::Value(n, Rc::new(chain));
        chain = node;
    }
    chain
}

fn print_chain<T>(chain: &Node<T>) where T: Display {
    let mut ptr = chain;
    while let Node::Value(n, next) = ptr {
        print!("{}", n);
        ptr = next;

        if let &Node::<T>::Value(_, _) = ptr {
            print!(" -> ");
        }
    }
    println!();
}

fn main() {
    let chain = build_chain_str();
    print_chain(&chain);

    let chain_usize = build_chain_usize();
    print_chain(&chain_usize);
}
