use std::fmt::{self, Write};
use ltk_meta::Bin;
use crate::{
cst::{self, Cst},
hashes::HashProvider,
print::{PrintConfig, PrintError},
};
pub struct CstPrinter<'a, W: Write> {
visitor: super::visitor::CstVisitor<'a, W>,
}
impl<'a, W: Write> CstPrinter<'a, W> {
pub fn new(src: &'a str, out: W, config: PrintConfig<()>) -> Self {
Self {
visitor: super::visitor::CstVisitor::new(src, out, config),
}
}
pub fn print(mut self, cst: &Cst) -> Result<usize, PrintError> {
cst.walk(&mut self.visitor);
self.visitor.flush()?;
if let Some(e) = self.visitor.error {
return Err(e);
}
Ok(self.visitor.printed_bytes())
}
}
pub struct BinPrinter<H: HashProvider = ()> {
buffer: String,
config: PrintConfig<H>,
}
impl BinPrinter<()> {
pub fn new() -> Self {
Self::default()
}
}
impl<H: HashProvider> BinPrinter<H> {
pub fn with_config<H2: HashProvider>(self, config: PrintConfig<H2>) -> BinPrinter<H2> {
BinPrinter {
buffer: self.buffer,
config,
}
}
pub fn print<W: fmt::Write + ?Sized>(
self,
tree: &Bin,
writer: &mut W,
) -> Result<usize, PrintError>
where
H: Clone,
{
let (config, hashes) = self.config.take_hashes();
let builder = cst::builder::Builder::new().with_hashes(hashes);
let (cst, buf) = builder.build(tree);
CstPrinter::new(&buf, writer, config).print(&cst)
}
pub fn print_to_string(self, tree: &Bin) -> Result<String, PrintError>
where
H: Clone,
{
let mut str = String::new();
self.print(tree, &mut str)?;
Ok(str)
}
}
impl Default for BinPrinter<()> {
fn default() -> Self {
Self {
buffer: String::new(),
config: PrintConfig::default(),
}
}
}