use std::ops::Deref;
use std::rc::Rc;
use std::fmt::{self, Debug};
use std::iter::{IntoIterator, Iterator};
use std::iter::FromIterator;
pub trait AbstractStack<T> where Self: std::marker::Sized {
fn push(&self, val: T) -> Self;
fn pop(&self) -> Option<Self>;
fn iter(&self) -> StackIterator<T>;
fn peek(&self) -> Option<&T>;
fn depth(&self) -> usize {
self.iter().count()
}
}
pub trait Collect<T>: AbstractStack<T> where T: Clone {
fn as_vec(&self) -> Vec<T> {
let mut v = Vec::new();
for el in self.iter().map(|ref node| node.deref().clone()) {
v.push(el)
} v
}
}
struct StackNode<T> {
value: T,
parent: Option<Stack<T>>,
}
struct Empty<T>(Option<T>);
pub struct Stack<T>(Rc<StackNode<T>>);
impl<T> Clone for Stack<T> {
fn clone(&self) -> Self {
Stack(self.0.clone())
}
}
impl<T> Stack<T> {
pub fn iter(&self) -> StackIterator<T> {
self.into_iter()
}
pub fn root(val: T) -> Self {
Stack(Rc::from(StackNode {
value: val,
parent: None,
}))
}
pub fn push(&self, val: T) -> Self {
Stack(Rc::from(StackNode {
value: val,
parent: Some(Stack(self.0.clone())),
}))
}
pub fn pop(&self) -> Option<Self> {
match self.0.parent {
None => None,
Some(ref p) => Some(p.clone()),
}
}
pub fn peek(&self) -> Option<&T> {
Some(self.deref())
}
}
impl<T> AbstractStack<T> for Stack<T> {
fn push(&self, val: T) -> Self {
self.push(val)
}
fn pop(&self) -> Option<Self> {
self.pop()
}
fn iter(&self) -> StackIterator<T> {
self.iter()
}
fn peek(&self) -> Option<&T> {
self.peek()
}
}
impl<T> Deref for Stack<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0.deref().value
}
}
impl<T: Debug> Debug for Stack<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "S<{:?}>", **self)
}
}
impl<T> Debug for Empty<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "-Empty-")
}
}
impl<'a, T> IntoIterator for &'a Stack<T> {
type Item = Stack<T>;
type IntoIter = StackIterator<T>;
fn into_iter(self) -> StackIterator<T> {
StackIterator { current: Some(self.clone()) }
}
}
pub struct StackIterator<T> {
current: Option<Stack<T>>,
}
impl<T> Iterator for StackIterator<T> {
type Item = Stack<T>;
fn next(&mut self) -> Option<Stack<T>> {
let cur = self.current.take();
self.current = cur.as_ref().and_then(|s| s.pop());
cur
}
}
pub struct NStack<T>(Option<Stack<T>>);
impl<T> NStack<T> {
pub fn new() -> Self {
NStack(None)
}
pub fn iter(&self) -> StackIterator<T> {
match self.0 {
None => StackIterator { current: None },
Some(ref stack) => stack.into_iter()
}
}
pub fn try_into(&self) -> Option<Stack<T>> {
self.0.as_ref().map(|stack| stack.clone())
}
pub fn unwrap(&self) -> Stack<T> {
self.try_into().unwrap()
}
pub fn push(&self, val: T) -> Self {
NStack(Some(Stack::root(val)))
}
pub fn peek(&self) -> Option<&T> {
self.0.as_ref().map(|s|s.deref())
}
}
impl<T> AbstractStack<T> for NStack<T> {
fn push(&self, val: T) -> Self {
self.push(val)
}
fn pop(&self) -> Option<Self> {
self.0.as_ref()
.map(|stack| NStack(stack.pop()))
}
fn iter(&self) -> StackIterator<T> {
self.iter()
}
fn peek(&self) -> Option<&T> {
self.peek()
}
}
#[test]
fn test_empty() {
let root = NStack::new();
let x = root.push(1);
println!("{:?}", root.iter().count());
println!("{:?}", x.iter().count());
println!("XXXX: {:?}", *x.unwrap());
}