use std::io::Write;
use crate::error::Result;
use crate::etree::Directive;
use crate::etree::ParseOps;
use crate::etree::TextNode;
use crate::etree::TextTree;
use crate::utils;
const DATA_BYTES_PER_LINE: usize = 48;
pub fn tree_write<W: Write>(outw: &mut W, text: &TextTree, paops: &mut ParseOps) -> Result<()> {
for elem in text {
match elem {
TextNode::Plain(line) => writeln!(outw, "{}", line)?,
TextNode::BeginEnd { keyw, txt } => {
writeln!(
outw,
"{} {} {} {}",
paops.separators.left,
Directive::Begin.keyword(),
keyw,
paops.separators.right
)?;
paops.runtime.level += 1;
tree_write(outw, txt, paops)?;
paops.runtime.level -= 1;
writeln!(
outw,
"{} {} {} {}",
paops.separators.left,
Directive::End.keyword(),
keyw,
paops.separators.right
)?;
}
TextNode::Encrypted {
keyw,
txt,
extfields,
} => {
write!(
outw,
"{} {} {}",
paops.separators.left,
Directive::Encrypted.keyword(),
keyw
)?;
if let TextNode::Stored { keyw: _, cas } = &txt[0] {
write!(outw, " {}", cas)?;
for (key, value) in extfields.iter() {
write!(outw, " {}:{}", key, value)?;
}
writeln!(outw, " {}", paops.separators.right)?;
} else {
for (key, value) in extfields.iter() {
write!(outw, " {}:{}", key, value)?;
}
writeln!(outw, " {}", paops.separators.right)?;
paops.runtime.level += 1;
tree_write(outw, txt, paops)?;
paops.runtime.level -= 1;
writeln!(
outw,
"{} {} {} {}",
paops.separators.left,
Directive::End.keyword(),
keyw,
paops.separators.right
)?;
}
}
TextNode::Stored { keyw, cas } => {
writeln!(
outw,
"{} {} {} {} {}",
paops.separators.left,
Directive::Stored.keyword(),
keyw,
cas,
paops.separators.right
)?;
}
TextNode::Data(data) => {
for chunk in data.chunks(DATA_BYTES_PER_LINE) {
writeln!(
outw,
"{} {} {} {}",
paops.separators.left,
Directive::Data.keyword(),
utils::base64_encode(chunk)?,
paops.separators.right
)?;
}
}
TextNode::Chain { extfields } => {
write!(
outw,
"{} {}",
paops.separators.left,
Directive::Chain.keyword()
)?;
for (key, value) in extfields.iter() {
write!(outw, " {}:{}", key, value)?;
}
writeln!(outw, " {}", paops.separators.right)?;
}
TextNode::Include { hash } => {
writeln!(
outw,
"{} {} {} {}",
paops.separators.left,
Directive::Include.keyword(),
hash,
paops.separators.right
)?;
}
TextNode::Conflict { keyw, ours, theirs } => {
writeln!(
outw,
"{} {} {} {}",
paops.separators.left,
Directive::Conflict.keyword(),
keyw,
paops.separators.right
)?;
paops.runtime.level += 1;
writeln!(
outw,
"{} {} {}",
paops.separators.left,
Directive::Ours.keyword(),
paops.separators.right
)?;
tree_write(outw, ours, paops)?;
writeln!(
outw,
"{} {} {}",
paops.separators.left,
Directive::Theirs.keyword(),
paops.separators.right
)?;
tree_write(outw, theirs, paops)?;
paops.runtime.level -= 1;
writeln!(
outw,
"{} {} {} {}",
paops.separators.left,
Directive::End.keyword(),
keyw,
paops.separators.right
)?;
}
}
}
Ok(())
}