use crate::NodeFormat;
#[allow(missing_docs)]
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Color {
Black,
White,
Red,
Green,
Yellow,
Blue,
Magenta,
Cyan,
Custom(usize),
}
impl From<Color> for usize {
fn from(color: Color) -> Self {
match color {
Color::Black => 30,
Color::White => 37,
Color::Red => 31,
Color::Green => 32,
Color::Yellow => 33,
Color::Blue => 34,
Color::Magenta => 35,
Color::Cyan => 36,
Color::Custom(c) => c,
}
}
}
pub struct LineGlyphBuilder {
vertical: char,
horizontal: char,
crossing: char,
arrow_down: char,
}
impl LineGlyphBuilder {
pub const fn ascii() -> Self {
Self {
vertical: '|',
horizontal: '-',
crossing: '+',
arrow_down: 'V',
}
}
pub const fn vertical(mut self, glyph: char) -> Self {
self.vertical = glyph;
self
}
pub const fn horizontal(mut self, glyph: char) -> Self {
self.horizontal = glyph;
self
}
pub const fn crossing(mut self, glyph: char) -> Self {
self.crossing = glyph;
self
}
pub const fn arrow_down(mut self, glyph: char) -> Self {
self.arrow_down = glyph;
self
}
pub const fn finish(self) -> LineGlyphs {
LineGlyphs {
vertical: self.vertical,
horizontal: self.horizontal,
crossing: self.crossing,
arrow_down: self.arrow_down,
}
}
}
pub struct LineGlyphs {
pub(crate) vertical: char,
pub(crate) horizontal: char,
pub(crate) crossing: char,
pub(crate) arrow_down: char,
}
impl From<LineGlyphBuilder> for LineGlyphs {
fn from(builder: LineGlyphBuilder) -> Self {
builder.finish()
}
}
pub struct Config<ID, T> {
pub(crate) formatter: Box<dyn NodeFormat<ID, T>>,
pub(crate) color_palette: Option<Vec<Color>>,
pub(crate) max_per_layer: usize,
max_glyphs_per_layer: usize,
pub(crate) vertical_edge_spacing: usize,
pub(crate) line_glyphs: LineGlyphs,
}
impl<ID, T> Config<ID, T> {
pub fn new<F>(nfmt: F, max_per_layer: usize) -> Self
where
F: NodeFormat<ID, T> + 'static,
{
Self {
formatter: Box::new(nfmt),
color_palette: None,
max_per_layer,
max_glyphs_per_layer: usize::MAX,
vertical_edge_spacing: 1,
line_glyphs: LineGlyphBuilder::ascii().finish(),
}
}
pub fn vertical_edge_spacing(mut self, n_spacing: usize) -> Self {
self.vertical_edge_spacing = n_spacing;
self
}
pub fn formatter<F>(mut self, nfmt: F) -> Self
where
F: NodeFormat<ID, T> + 'static,
{
self.formatter = Box::new(nfmt);
self
}
pub fn max_per_layer(mut self, count: usize) -> Self {
self.max_per_layer = count;
self
}
pub fn default_colors(mut self) -> Self {
self.color_palette = Some(vec![
Color::Red,
Color::Green,
Color::Yellow,
Color::Blue,
Color::Magenta,
Color::Cyan,
]);
self
}
pub fn custom_colors(mut self, colors: Vec<Color>) -> Self {
self.color_palette = Some(colors);
self
}
pub fn disable_colors(mut self) -> Self {
self.color_palette = None;
self
}
pub fn line_glyphs<L>(mut self, glyphs: L) -> Self
where
L: Into<LineGlyphs>,
{
self.line_glyphs = glyphs.into();
self
}
pub fn max_glyphs_per_layer(mut self, max: usize) -> Self {
self.max_glyphs_per_layer = max;
self
}
pub(crate) fn glyph_width(&self) -> usize {
self.max_glyphs_per_layer
}
}