use std::fs::File;
use std::io::{LineWriter, Write};
use std::path::Path;
use failure::Fallible;
use crate::fst_traits::final_states_iterator::FinalStatesIterator;
use crate::fst_traits::Fst;
use crate::semirings::Semiring;
use crate::DrawingConfig;
pub trait ExpandedFst: Fst {
fn num_states(&self) -> usize;
fn write_text<P: AsRef<Path>>(&self, path_output: P) -> Fallible<()> {
let buffer = File::create(path_output.as_ref())?;
let mut line_writer = LineWriter::new(buffer);
write_fst!(self, line_writer, true);
Ok(())
}
fn text(&self) -> Fallible<String> {
let buffer = Vec::<u8>::new();
let mut line_writer = LineWriter::new(buffer);
write_fst!(self, line_writer, true);
Ok(String::from_utf8(line_writer.into_inner()?)?)
}
fn draw<P: AsRef<Path>>(&self, path_output: P, config: &DrawingConfig) -> Fallible<()> {
let buffer = File::create(path_output.as_ref())?;
let mut f = LineWriter::new(buffer);
if let Some(start_state) = self.start() {
writeln!(f, "digraph FST {{")?;
if config.vertical {
writeln!(f, "rankdir = BT;")?;
} else {
writeln!(f, "rankdir = LR;")?;
}
writeln!(f, "size = \"{},{}\";", config.width, config.height)?;
writeln!(f, "label = {};", config.title)?;
writeln!(f, "center = 1;")?;
if config.portrait {
writeln!(f, "orientation = Portrait;")?;
} else {
writeln!(f, "orientation = Landscape;")?;
}
writeln!(f, "ranksep = {}", config.ranksep)?;
writeln!(f, "nodesep = {}", config.nodesep)?;
draw_single_state!(self, start_state, f, config);
for state in self.states_iter() {
if state != start_state {
draw_single_state!(self, state, f, config);
}
}
writeln!(f, "}}")?;
}
Ok(())
}
}