hedel-rs 0.1.0

A Hierarchical Doubly Linked List.
Documentation
use crate::{
	node::{
		Node,
		Content,
	}
};
use std::{
	fmt::Debug,
	ops::Deref
};

/// `NodeList` concreatly is its first `Node`.
/// This design allows for sibling nodes at the root-level.
/// Automatically dereferences to the first node in the linked list
/// when calling any `Node`'s method on it.
/// 
/// Usually generated by the `list` macro.
///
/// # Example
///
/// ```
/// let list = list!(
///		node!(1, node!(2)),
///		node!(3),
///		node!(4)
/// ); 
/// 
/// // derefernces to the first node and retrives its first child.
/// assert_eq!(list.child().unwrap().to_content(), 2);
/// assert_eq!(list.get_last_sibling().unwrap().to_content(), 4);
/// ```

#[derive(Debug, Clone)]
pub struct NodeList<T: Debug + Clone>(pub Option<Node<T>>);

/// `NodeList` derefernces to `Node` or panics when empty.
impl<'a, T: Debug + Clone> Deref for NodeList<T> {
	type Target = Node<T>;

	fn deref(&self) -> &Node<T> {
		if let Some(ref node) = self.0 {
			return node;
		} panic!("Can't deref NodeList(None) to Node<T>. Tried dereferencing to T on Option<T>::None.");
	}
}

impl<T: Debug + Clone> NodeList<T> {
	pub fn new(node: Node<T>) -> Self {
		let content = Box::new(node.get().content.clone());
		node.get_mut().content = Content::List(content);
		Self(Some(node))
	}
}
/*
	pub fn find_sibling<P: NodeComparable<T>>(&self, ident: &P) -> Option<Node<T>> {

		if let Some(s) = &self.0 {
			if let Some(sib) = s.find_next(ident) {
				return Some(sib);
			} 
			if ident.compare(&s) {
				return Some(s.clone());
			}
		}

		None
	}
	
	pub fn find_linked_list<P: NodeComparable<T>>(&self, ident: &P) -> Option<Node<T>> {
	
		if let Some(s) = &self.0 {
			if let Some(sib) = s.find_next(ident) {
				return Some(sib);
			} 
			if ident.compare(&s) {
				return Some(s.clone());
			}
		}

		None	
	}
}

impl<T: Debug + Clone> GetNode<T> for NodeList<T> {
	
	fn get_first_sibling(&self) -> Option<Node<T>> {
		if let Some(s) = &self.0 {
			return Some(s.clone());
		} None
	}

	fn get_last_sibling(&self) -> Option<Node<T>> {
		if let Some(s) = &self.0 {
			if let Some(last) = s.get_last_sibling() {
				return Some(last);
			} 
			
			return Some(s.clone());
		} None
	}

	fn get_last_child(&self) -> Option<Node<T>> {
		if let Some(_) = self.0.get().next {
			return self.0.get_last_child();
		} self.get_last_sibling()
	}
}

impl<T: Debug + Clone, I: CompareNode<T>> FindNode<T> for NodeList<T> {
	fn find_next(&self, ident: &T) -> Option<Node<T>> {
		
	}	
}

impl<T: Debug + Clone> AppendNode<T> for NodeList<T> {

}

impl<T: Debug + Clone>CollectNode for NodeList<T> {

}

*/
/// Generate a linked list blazingly fast and append any number of `Nodes`
/// 
/// # Example
///
/// ```
/// let my_list = list!{
/// 	node!(2, node!(3)),
///		node!(45),
///		node!(36)
/// };
/// ```
#[macro_export]
macro_rules! list {
	($($node: expr),*) => {
		{
			let mut children: Vec<hedel_rs::Node<_>> = Vec::new();
			let mut lists: Vec<usize> = Vec::new();
			let mut c = 0;

			$(
				let n: hedel_rs::Node::<_> = $node.into();
				
				if let hedel_rs::Content::List(_) = n.get().content {
					lists.push(c as usize);
				}

				children.push(n);

				c += 1;

			)*

			if children.len() > 0 {
				
				c = 0;

				for ref child in &children {
					
					let mut borrow = child.get_mut();
					
					if c != children.len() - 1 {
						borrow.next = Some(children[c + 1].clone()); 
					}

					if c != 0 {
						borrow.prev = Some(children[c - 1].downgrade());
					}

					borrow.parent = None;

					c += 1;
				}
			}
	
			for idx in lists.into_iter() {
				
				let first = children[idx].clone();

				if idx > 0 {
					if let Some(prev) = children.get(idx - 1) {
						prev.get_mut().next = Some(first.clone());
						first.get_mut().prev = Some(prev.downgrade());
					}
				}

				if let Some(last) = first.get_last_sibling() {
					if let Some(next) = children.get(idx + 1) {
						next.get_mut().prev = Some(last.downgrade());
						last.get_mut().next = Some(next.clone());
					}
				}
			}

			hedel_rs::NodeList::new(children[0].clone())
		}
	}
}