use std::{
rc::{
Weak,
Rc
}
};
use std::fmt::Debug;
use crate::cell::{
HedelCell,
RefHedel,
RefMutHedel,
};
use crate::{
list::{
WeakList,
List
}
};
use crate::errors::HedelError;
#[derive(Debug, Clone)]
pub struct NodeInner<T: Debug + Clone> {
pub next: Option<Node<T>>,
pub prev: Option<WeakNode<T>>,
pub child: Option<Node<T>>,
pub parent: Option<WeakNode<T>>,
pub list: Option<WeakList<T>>,
pub content: T
}
#[derive(Debug, Clone)]
pub struct WeakNode<T: Debug + Clone> {
pub inner: Weak<HedelCell<NodeInner<T>>>
}
impl<T: Debug + Clone> WeakNode<T> {
pub fn upgrade(&self) -> Option<Node<T>> {
Some(Node::<T> {
inner: self.inner.upgrade()?
})
}
}
#[derive(Debug)]
pub struct Node<T: Debug + Clone > {
pub inner: Rc<HedelCell<NodeInner<T>>>,
}
impl<T: Debug + Clone> Clone for Node<T> {
fn clone(&self) -> Self {
Self {
inner: Rc::clone(&self.inner),
}
}
}
impl<T: Debug + Clone> Node<T> {
pub fn new(content: T) -> Self {
Self {
inner: Rc::new(HedelCell::new(NodeInner::<T> {
next: None,
prev: None,
child: None,
parent: None,
list: None,
content
})),
}
}
pub fn downgrade(&self) -> WeakNode<T> {
WeakNode {
inner: Rc::downgrade(&self.inner)
}
}
pub fn try_get(&self) -> Result<RefHedel<NodeInner<T>>, HedelError> {
Ok(self.inner.try_get()?)
}
pub fn get(&self) -> RefHedel<NodeInner<T>> {
self.inner.get()
}
pub fn try_get_mut(&self) -> RefMutHedel<'_, NodeInner<T>> {
self.inner.get_mut()
}
pub fn get_mut(&self) -> RefMutHedel<'_, NodeInner<T>> {
self.inner.get_mut()
}
pub fn next(&self) -> Option<Node<T>> {
self.get().next.clone()
}
pub fn prev(&self) -> Option<Node<T>> {
if let Some(ref p) = self.get().prev {
return p.upgrade()
} None
}
pub fn parent(&self) -> Option<Node<T>> {
if let Some(ref p) = self.get().parent {
return p.upgrade();
} None
}
pub fn list(&self) -> Option<List<T>> {
if let Some(ref l) = self.get().list {
return Some(l.upgrade()?);
} None
}
pub fn child(&self) -> Option<Node<T>> {
self.get().child.clone()
}
pub fn to_content(self) -> T {
self.get().content.clone()
}
pub fn free(&self) {
let mut node = self.get_mut();
node.parent = None;
node.next = None;
node.prev = None;
}
}
#[macro_export]
macro_rules! as_content {
($self: expr, |$ident: ident| $cl: expr) => {
{
let $ident = $self.get().content;
$cl
}
}
}
pub trait DetachNode<T: Debug + Clone> {
fn detach(&self);
fn detach_preserve(&self, vec: &mut NodeCollection<T>);
}
impl<T: Debug + Clone> DetachNode<T> for Node<T> {
fn detach(&self) {
let mut tuple: (Option<Node<T>>, Option<Node<T>>) = ( None, None );
if let Some(one) = self.prev() {
if let Some(three) = self.next() {
tuple = (Some(one), Some(three));
} else {
tuple = (Some(one), None);
}
} else {
if let Some(three) = self.next() {
tuple = ( None, Some(three));
}
}
match tuple {
(Some(one), Some(three)) => {
one.get_mut().next = Some(three.clone());
three.get_mut().prev = Some(one.downgrade());
},
(Some(one), None) => {
one.get_mut().next = None;
},
(None, Some(three)) => {
three.get_mut().prev = None;
if let Some(parent) = self.parent() {
parent.get_mut().child = Some(three.clone());
}
},
(None, None) => {
if let Some(parent) = self.parent() {
parent.get_mut().child = None;
}
}
}
self.free();
}
fn detach_preserve(&self, vec: &mut NodeCollection<T>) {
let mut tuple: (Option<Node<T>>, Option<Node<T>>) = ( None, None );
if let Some(one) = self.prev() {
if let Some(three) = self.next() {
tuple = (Some(one), Some(three));
} else {
tuple = (Some(one), None);
}
} else {
if let Some(three) = self.next() {
tuple = ( None, Some(three));
}
}
match tuple {
(Some(one), Some(three)) => {
one.get_mut().next = Some(three.clone());
three.get_mut().prev = Some(one.downgrade());
},
(Some(one), None) => {
one.get_mut().next = None;
},
(None, Some(three)) => {
three.get_mut().prev = None;
if let Some(parent) = self.parent() {
parent.get_mut().child = Some(three.clone());
}
},
(None, None) => {
if let Some(parent) = self.parent() {
parent.get_mut().child = None;
}
}
}
vec.push(self.clone());
}
}
pub struct NodeCollection<T: Debug + Clone> {
pub nodes: Vec<Node<T>>
}
impl<T: Debug + Clone> NodeCollection<T> {
pub fn from_vec(nodes: Vec<Node<T>>) -> Self {
Self {
nodes
}
}
pub fn new() -> Self {
Self {
nodes: Vec::new()
}
}
pub fn into_nodes(self) -> Vec<Node<T>> {
self.nodes
}
pub fn as_nodes(&self) -> &Vec<Node<T>> {
&self.nodes
}
pub fn as_mut_nodes(&mut self) -> &mut Vec<Node<T>> {
&mut self.nodes
}
pub fn push(&mut self, node: Node<T>) {
self.nodes.push(node);
}
pub fn free(&self) {
for node in self.nodes.iter() {
node.free();
}
}
}
impl<T: Debug + Clone> IntoIterator for NodeCollection<T> {
type Item = Node<T>;
type IntoIter = std::vec::IntoIter<Node<T>>;
fn into_iter(self) -> Self::IntoIter {
self.nodes.into_iter()
}
}
pub trait CompareNode<T: Debug + Clone> {
fn compare(&self, node: &Node<T>) -> bool;
}
pub trait CollectNode<T: Debug + Clone, I: CompareNode<T>> {
fn collect_siblings(&self, ident: &I) -> NodeCollection<T>;
fn collect_children(&self, ident: &I) -> NodeCollection<T>;
fn collect_linked_list(&self, ident: &I) -> NodeCollection<T>;
}
impl<T: Debug + Clone, I: CompareNode<T>> CollectNode<T, I> for Node<T> {
fn collect_siblings(&self, ident: &I) -> NodeCollection<T> {
let mut collection = Vec::new();
if ident.compare(&self) {
collection.push(self.clone());
}
let mut current;
if let Some(prev) = self.prev() {
{
current = prev;
if ident.compare(¤t) {
collection.push(current.clone());
}
} while let Some(prev) = current.prev() {
current = prev;
if ident.compare(¤t) {
collection.push(current.clone());
}
}
}
if let Some(next) = self.next() {
{
current = next;
if ident.compare(¤t) {
collection.push(current.clone());
}
} while let Some(next) = current.next() {
current = next;
if ident.compare(¤t) {
collection.push(current.clone());
}
}
}
NodeCollection::<T>::from_vec(collection)
}
fn collect_children(&self, ident: &I) -> NodeCollection<T> {
let mut collection = Vec::new();
if let Some(child) = self.child() {
let mut child = child;
while let Some(c) = child.child() {
child = c;
if ident.compare(&child) {
collection.push(child.clone());
}
if let Some(prev) = child.prev() {
let mut prev = prev;
{
if ident.compare(&prev) {
collection.push(prev.clone());
}
collection.extend(prev.collect_children(ident).nodes);
} while let Some(p) = prev.prev() {
prev = p;
if ident.compare(&prev) {
collection.push(prev.clone());
}
collection.extend(prev.collect_children(ident).nodes);
}
}
if let Some(n) = child.next() {
let mut next = n;
{
if ident.compare(&next) {
collection.push(next.clone());
}
collection.extend(next.collect_children(ident).nodes);
} while let Some(n) = next.next() {
next = n;
if ident.compare(&next) {
collection.push(next.clone());
}
collection.extend(next.collect_children(ident).nodes);
}
}
}
}
NodeCollection::<T>::from_vec(collection)
}
fn collect_linked_list(&self, ident: &I) -> NodeCollection<T> {
let mut collection = Vec::new();
if let Some(parent) = self.parent() {
let mut parent = parent;
while let Some(p) = parent.parent() {
parent = p;
}
if ident.compare(&parent) {
collection.push(parent.clone());
}
collection.extend(parent.collect_children(ident).nodes);
if let Some(n) = parent.prev() {
let mut prev = n;
{
if ident.compare(&prev) {
collection.push(prev.clone());
}
collection.extend(prev.collect_children(ident).nodes);
} while let Some(n) = prev.prev() {
prev = n;
if ident.compare(&prev) {
collection.push(prev.clone());
}
collection.extend(prev.collect_children(ident).nodes);
}
}
if let Some(n) = parent.next() {
let mut next = n;
{
if ident.compare(&next) {
collection.push(next.clone());
}
collection.extend(next.collect_children(ident).nodes);
} while let Some(n) = next.next() {
next = n;
if ident.compare(&next) {
collection.push(next.clone());
}
collection.extend(next.collect_children(ident).nodes);
}
}
} else {
if ident.compare(&self) {
collection.push(self.clone());
}
collection.extend(self.collect_children(ident).nodes);
if let Some(n) = self.prev() {
let mut prev = n;
{
if ident.compare(&prev) {
collection.push(prev.clone());
}
collection.extend(prev.collect_children(ident).nodes);
} while let Some(n) = prev.prev() {
prev = n;
if ident.compare(&prev) {
collection.push(prev.clone());
}
collection.extend(prev.collect_children(ident).nodes);
}
}
if let Some(n) = self.next() {
let mut next = n;
{
if ident.compare(&next) {
collection.push(next.clone());
}
collection.extend(next.collect_children(ident).nodes);
} while let Some(n) = next.next() {
next = n;
if ident.compare(&next) {
collection.push(next.clone());
}
collection.extend(next.collect_children(ident).nodes);
}
}
}
NodeCollection::<T>::from_vec(collection)
}
}
pub trait FindNode<T: Debug + Clone, I: CompareNode<T>> {
fn find_next(&self, ident: &I) -> Option<Node<T>>;
fn find_prev(&self, ident: &I) -> Option<Node<T>>;
fn find_sibling(&self, ident: &I) -> Option<Node<T>>;
fn find_child(&self, ident: &I) -> Option<Node<T>>;
fn find_linked_list(&self, ident: &I) -> Option<Node<T>>;
}
impl<T: Debug + Clone, I: CompareNode<T>> FindNode<T, I> for Node<T> {
fn find_next(&self, ident: &I) -> Option<Node<T>> {
if let Some(next) = self.next() {
let mut next = next;
{
if ident.compare(&next) {
return Some(next);
}
} while let Some(n) = next.next() {
next = n;
if ident.compare(&next) {
return Some(next);
}
}
}
None
}
fn find_prev(&self, ident: &I) -> Option<Node<T>> {
if let Some(prev) = self.prev() {
let mut prev = prev;
{
if ident.compare(&prev) {
return Some(prev);
}
} while let Some(n) = prev.prev() {
prev = n;
if ident.compare(&prev) {
return Some(prev);
}
}
}
None
}
fn find_linked_list(&self, ident: &I) -> Option<Node<T>> {
if let Some(parent) = self.parent() {
let mut parent = parent;
while let Some(p) = parent.parent() {
parent = p;
}
if ident.compare(&parent) {
return Some(parent);
}
if let Some(c) = parent.find_child(ident) {
return Some(c);
}
if let Some(n) = parent.prev() {
let mut prev = n;
{
if ident.compare(&prev) {
return Some(prev);
}
if let Some(c) = prev.find_child(ident) {
return Some(c);
}
} while let Some(n) = prev.prev() {
prev = n;
if ident.compare(&prev) {
return Some(prev);
}
if let Some(c) = prev.find_child(ident) {
return Some(c);
}
}
}
if let Some(n) = parent.next() {
let mut next = n;
{
if ident.compare(&next) {
return Some(next);
}
if let Some(c) = next.find_child(ident) {
return Some(c);
}
} while let Some(n) = next.next() {
next = n;
if ident.compare(&next) {
return Some(next);
}
if let Some(c) = next.find_child(ident) {
return Some(c);
}
}
}
} else {
if ident.compare(&self) {
return Some(self.clone());
}
if let Some(child) = self.find_child(ident) {
return Some(child);
}
if let Some(n) = self.prev() {
let mut prev = n;
{
if ident.compare(&prev) {
return Some(prev);
}
if let Some(child) = prev.find_child(ident) {
return Some(child);
}
} while let Some(n) = prev.prev() {
prev = n;
if ident.compare(&prev) {
return Some(prev);
}
if let Some(child) = prev.find_child(ident) {
return Some(child);
}
}
}
if let Some(n) = self.next() {
let mut next = n;
{
if ident.compare(&next) {
return Some(next);
}
if let Some(child) = next.find_child(ident) {
return Some(child);
}
} while let Some(n) = next.next() {
next = n;
if ident.compare(&next) {
return Some(next);
}
if let Some(child) = next.find_child(ident) {
return Some(child);
}
}
}
}
None
}
fn find_child(&self, ident: &I) -> Option<Node<T>> {
if let Some(child) = self.child() {
let mut child = child;
{
if ident.compare(&child) {
return Some(child);
}
if let Some(next) = child.next() {
let mut next = next;
{
if ident.compare(&next) {
return Some(next);
}
if let Some(c) = next.find_child(ident) {
return Some(c);
}
} while let Some(n) = next.next() {
next = n;
if ident.compare(&next) {
return Some(next);
}
if let Some(c) = next.find_child(ident) {
return Some(c);
}
}
}
} while let Some(c) = child.child() {
child = c;
if ident.compare(&child) {
return Some(child);
}
if let Some(next) = child.next() {
let mut next = next;
{
if ident.compare(&next) {
return Some(next);
}
if let Some(c) = next.find_child(ident) {
return Some(c);
}
} while let Some(n) = next.next() {
next = n;
if ident.compare(&next) {
return Some(next);
}
if let Some(c) = next.find_child(ident) {
return Some(c);
}
}
}
}
}
None
}
fn find_sibling(&self, ident: &I) -> Option<Node<T>> {
if let Some(n) = self.prev() {
let mut prev = n;
{
if ident.compare(&prev) {
return Some(prev);
}
if let Some(child) = prev.find_child(ident) {
return Some(child);
}
} while let Some(n) = prev.prev() {
prev = n;
if ident.compare(&prev) {
return Some(prev);
}
if let Some(child) = prev.find_child(ident) {
return Some(child);
}
}
}
if let Some(n) = self.next() {
let mut next = n;
{
if ident.compare(&next) {
return Some(next);
}
if let Some(child) = next.find_child(ident) {
return Some(child);
}
} while let Some(n) = next.next() {
next = n;
if ident.compare(&next) {
return Some(next);
}
if let Some(child) = next.find_child(ident) {
return Some(child);
}
}
}
None
}
}
pub trait GetNode<T: Debug + Clone> {
fn get_first_sibling(&self) -> Option<Node<T>>;
fn get_last_sibling(&self) -> Option<Node<T>>;
fn get_last_child(&self) -> Option<Node<T>>;
}
impl<T: Debug + Clone> GetNode<T> for Node<T> {
fn get_first_sibling(&self) -> Option<Node<T>> {
if let Some(parent) = self.parent() {
return parent.child();
}
let mut first;
{
if let Some(prev) = self.prev() {
first = prev;
} else { return None; }
} while let Some(prev) = first.prev() {
first = prev;
}
Some(first)
}
fn get_last_sibling(&self) -> Option<Node<T>> {
let mut last;
{
if let Some(next) = self.next() {
last = next;
} else { return None; }
} while let Some(next) = last.next() {
last = next;
}
Some(last)
}
fn get_last_child(&self) -> Option<Node<T>> {
if let Some(child) = self.child() {
let child = child;
if let Some(s) = child.get_last_sibling() {
return Some(s);
}
return Some(child);
} None
}
}
pub trait AppendNode<T: Debug + Clone> {
fn append_next(&self, node: Node<T>);
fn append_child(&self, node: Node<T>);
fn append_prev(&self, node: Node<T>);
}
impl<T: Debug + Clone> AppendNode<T> for Node<T> {
fn append_next(&self, node: Node<T>) {
if let Some(parent) = self.parent() {
node.get_mut().parent = Some(parent.downgrade());
}
if let Some(next) = self.next() {
next.get_mut().prev = Some(node.downgrade());
node.get_mut().next = Some(next);
}
self.get_mut().next = Some(node.clone());
node.get_mut().prev = Some(self.downgrade());
}
fn append_prev(&self, node: Node<T>) {
if let Some(prev) = self.prev() {
prev.get_mut().next = Some(node.clone());
node.get_mut().prev = Some(prev.downgrade());
self.get_mut().prev = Some(node.downgrade());
node.get_mut().next = Some(self.clone());
} else {
if let Some(list) = self.list() {
self.get_mut().prev = Some(node.downgrade());
node.get_mut().next = Some(self.clone());
node.get_mut().list = Some(list.downgrade());
*list.first.get_mut() = Some(node.clone());
} else { }
}
if let Some(parent) = self.parent() {
node.get_mut().parent = Some(parent.downgrade());
parent.get_mut().child = Some(node.clone());
}
}
fn append_child(&self, node: Node<T>) {
node.get_mut().parent = Some(self.downgrade());
if let Some(last_child) = self.get_last_child() {
last_child.get_mut().next = Some(node.clone());
node.get_mut().prev = Some(last_child.downgrade());
} else {
self.get_mut().child = Some(node);
}
}
}
pub trait InsertNode<T: Debug + Clone> {
fn insert_sibling(&self, position: usize, node: Node<T>);
fn insert_child(&self, position: usize, node: Node<T>);
}
impl<T: Debug + Clone> InsertNode<T> for Node<T> {
fn insert_sibling(&self, position: usize, node: Node<T>) {
let mut sibling = self.clone();
let mut c = 0;
if c != position {
while let Some(sib) = sibling.next() {
sibling = sib;
c += 1;
if c == position {
break;
}
}
}
if c != position {
sibling.append_next(node.clone());
} else {
if let Some(parent) = self.parent() {
node.get_mut().parent = Some(parent.downgrade());
}
if let Some(prev) = sibling.prev() {
let previous = prev;
previous.get_mut().next = Some(node.clone());
} else {
if let Some(parent) = self.parent() {
parent.get_mut().child = Some(node.clone());
}
}
sibling.get_mut().prev = Some(node.downgrade());
}
}
fn insert_child(&self, position: usize, node: Node<T>) {
if let Some(first_child) = self.child() {
first_child.insert_sibling(position, node);
} else {
node.get_mut().parent = Some(self.downgrade());
self.get_mut().child = Some(node);
}
}
}
#[macro_export]
macro_rules! node {
($content: expr $(,$node: expr)*) => {
{
let mut node = hedel_rs::Node::new($content);
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 Some(_) = n.get().list {
lists.push(c as usize);
}
children.push(n);
c += 1;
)*
if children.len() > 0 {
node.get_mut().child = Some(children[0].clone());
c = 0;
let max_idx = children.len() - 1;
for ref child in &children {
let mut borrow = child.get_mut();
if c != max_idx {
borrow.next = Some(children[c + 1].clone());
}
if c != 0 {
borrow.prev = Some(children[c - 1].downgrade());
}
borrow.parent = Some(hedel_rs::WeakNode {
inner: std::rc::Rc::downgrade(&node.inner)
});
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());
}
}
let mut child = first;
{
child.get_mut().parent = Some(node.downgrade());
} while let Some(ch) = child.next() {
child = ch;
child.get_mut().parent = Some(node.downgrade());
}
}
node
}
}
}