use alloc::vec::Vec;
use crate::{Serializer, TreeNode};
pub fn serialize_tree(
serializer: &mut Serializer<'_, '_>,
root_node: &TreeNode,
break_line_at: usize,
) {
enum State<'a> {
Beginning(&'a TreeNode),
Writing {
stack: Vec<core::slice::Iter<'a, TreeNode>>,
current_list: core::slice::Iter<'a, TreeNode>,
list_beginning: bool,
},
Finished,
}
let mut state = State::Beginning(root_node);
loop {
match state {
State::Beginning(node) => match node {
TreeNode::Atom(atom) => {
serializer.put_atom(atom, break_line_at);
state = State::Finished;
}
TreeNode::List(list) => {
serializer.begin_list(break_line_at);
state = State::Writing {
stack: Vec::new(),
current_list: list.iter(),
list_beginning: true,
};
}
},
State::Writing {
ref mut stack,
ref mut current_list,
ref mut list_beginning,
} => {
if let Some(node) = current_list.next() {
match node {
TreeNode::Atom(atom) => {
if *list_beginning {
serializer.put_atom(atom, usize::MAX);
} else {
serializer.put_atom(atom, break_line_at);
}
*list_beginning = false;
}
TreeNode::List(list) => {
serializer.begin_list(break_line_at);
stack.push(core::mem::replace(current_list, list.iter()));
*list_beginning = true;
}
}
} else {
serializer.end_list();
if let Some(parent_list) = stack.pop() {
*current_list = parent_list;
*list_beginning = false;
} else {
state = State::Finished;
}
}
}
State::Finished => return,
}
}
}