use core::fmt;
use crate::membership::Membership;
use crate::node::IntraTreeLink;
use crate::node::debug_print::{FakeOption, RawStr};
#[derive(Clone, Copy)]
enum NodeType {
Plain,
Frozen,
Hot,
}
impl NodeType {
#[inline]
#[must_use]
fn name(self) -> &'static str {
match self {
Self::Plain => "Node",
Self::Frozen => "FrozenNode",
Self::Hot => "HotNode",
}
}
}
#[derive(Clone, Copy)]
pub struct DebugPrintNodeLocal<'a, T> {
link: &'a IntraTreeLink<T>,
membership: &'a Membership<T>,
node_type: NodeType,
}
impl<T: fmt::Debug> fmt::Debug for DebugPrintNodeLocal<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut ds = f.debug_struct(self.node_type.name());
match self.link.try_borrow_data() {
Ok(v) => ds.field("data", &v),
Err(_) => ds.field("data", &RawStr("<borrowed>")),
};
ds.field("parent", &FakeOption::some_if_true(!self.link.is_root()))
.field(
"prev_sibling",
&FakeOption::some_if_true(self.link.has_prev_sibling()),
)
.field(
"next_sibling",
&FakeOption::some_if_true(self.link.has_next_sibling()),
)
.field(
"first_child",
&FakeOption::some_if_true(self.link.has_children()),
)
.field(
"tree",
&(*self.membership.tree_core_ref()).debug_print_local(),
)
.finish()
}
}
impl<'a, T> DebugPrintNodeLocal<'a, T> {
#[inline]
#[must_use]
pub(in crate::node) fn new_plain(
link: &'a IntraTreeLink<T>,
membership: &'a Membership<T>,
) -> Self {
Self {
link,
membership,
node_type: NodeType::Plain,
}
}
#[inline]
#[must_use]
pub(in crate::node) fn new_frozen(
link: &'a IntraTreeLink<T>,
membership: &'a Membership<T>,
) -> Self {
Self {
link,
membership,
node_type: NodeType::Frozen,
}
}
#[inline]
#[must_use]
pub(in crate::node) fn new_hot(
link: &'a IntraTreeLink<T>,
membership: &'a Membership<T>,
) -> Self {
Self {
link,
membership,
node_type: NodeType::Hot,
}
}
}
#[derive(Clone, Copy)]
pub struct DebugPrintSubtree<'a, T> {
link: &'a IntraTreeLink<T>,
membership: &'a Membership<T>,
node_type: NodeType,
}
impl<T: fmt::Debug> fmt::Debug for DebugPrintSubtree<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut ds = f.debug_struct(self.node_type.name());
ds.field(
"tree",
&(*self.membership.tree_core_ref()).debug_print_local(),
);
match self.link.try_borrow_data() {
Ok(v) => ds.field("data", &v),
Err(_) => ds.field("data", &RawStr("<borrowed>")),
};
ds.field(
"children",
&DebugPrintSubtreeChildren {
link: self.link,
node_type: self.node_type,
},
)
.finish()
}
}
impl<'a, T> DebugPrintSubtree<'a, T> {
#[inline]
#[must_use]
pub(in crate::node) fn new_plain(
link: &'a IntraTreeLink<T>,
membership: &'a Membership<T>,
) -> Self {
Self {
link,
membership,
node_type: NodeType::Plain,
}
}
#[inline]
#[must_use]
pub(in crate::node) fn new_frozen(
link: &'a IntraTreeLink<T>,
membership: &'a Membership<T>,
) -> Self {
Self {
link,
membership,
node_type: NodeType::Plain,
}
}
#[inline]
#[must_use]
pub(in crate::node) fn new_hot(
link: &'a IntraTreeLink<T>,
membership: &'a Membership<T>,
) -> Self {
Self {
link,
membership,
node_type: NodeType::Hot,
}
}
}
#[derive(Clone, Copy)]
struct DebugPrintSubtreeChildren<'a, T> {
link: &'a IntraTreeLink<T>,
node_type: NodeType,
}
impl<T: fmt::Debug> fmt::Debug for DebugPrintSubtreeChildren<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut dl = f.debug_list();
let mut next_child = self.link.first_child_link();
while let Some(child) = next_child {
dl.entry(&DebugPrintSubtreeDescendant {
link: &child,
node_type: self.node_type,
});
next_child = child.next_sibling_link();
}
dl.finish()
}
}
#[derive(Clone, Copy)]
pub(crate) struct DebugPrintSubtreeDescendant<'a, T> {
link: &'a IntraTreeLink<T>,
node_type: NodeType,
}
impl<T: fmt::Debug> fmt::Debug for DebugPrintSubtreeDescendant<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut ds = f.debug_struct("Node");
match self.link.try_borrow_data() {
Ok(v) => ds.field("data", &v),
Err(_) => ds.field("data", &RawStr("<borrowed>")),
};
ds.field(
"children",
&DebugPrintSubtreeChildren {
link: self.link,
node_type: self.node_type,
},
)
.finish()
}
}
impl<'a, T> DebugPrintSubtreeDescendant<'a, T> {
#[inline]
#[must_use]
pub(crate) fn new_plain(link: &'a IntraTreeLink<T>) -> Self {
Self {
link,
node_type: NodeType::Plain,
}
}
}