use crate::symbols::{block, line};
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct Set<'a> {
pub top_left: &'a str,
pub top_right: &'a str,
pub bottom_left: &'a str,
pub bottom_right: &'a str,
pub vertical_left: &'a str,
pub vertical_right: &'a str,
pub horizontal_top: &'a str,
pub horizontal_bottom: &'a str,
}
impl Default for Set<'_> {
fn default() -> Self {
PLAIN
}
}
const fn from_line_set(line_set: line::Set<'_>) -> Set<'_> {
Set {
top_left: line_set.top_left,
top_right: line_set.top_right,
bottom_left: line_set.bottom_left,
bottom_right: line_set.bottom_right,
vertical_left: line_set.vertical,
vertical_right: line_set.vertical,
horizontal_top: line_set.horizontal,
horizontal_bottom: line_set.horizontal,
}
}
pub const PLAIN: Set = Set {
top_left: line::NORMAL.top_left,
top_right: line::NORMAL.top_right,
bottom_left: line::NORMAL.bottom_left,
bottom_right: line::NORMAL.bottom_right,
vertical_left: line::NORMAL.vertical,
vertical_right: line::NORMAL.vertical,
horizontal_top: line::NORMAL.horizontal,
horizontal_bottom: line::NORMAL.horizontal,
};
pub const ROUNDED: Set = Set {
top_left: line::ROUNDED.top_left,
top_right: line::ROUNDED.top_right,
bottom_left: line::ROUNDED.bottom_left,
bottom_right: line::ROUNDED.bottom_right,
vertical_left: line::ROUNDED.vertical,
vertical_right: line::ROUNDED.vertical,
horizontal_top: line::ROUNDED.horizontal,
horizontal_bottom: line::ROUNDED.horizontal,
};
pub const DOUBLE: Set = Set {
top_left: line::DOUBLE.top_left,
top_right: line::DOUBLE.top_right,
bottom_left: line::DOUBLE.bottom_left,
bottom_right: line::DOUBLE.bottom_right,
vertical_left: line::DOUBLE.vertical,
vertical_right: line::DOUBLE.vertical,
horizontal_top: line::DOUBLE.horizontal,
horizontal_bottom: line::DOUBLE.horizontal,
};
pub const THICK: Set = Set {
top_left: line::THICK.top_left,
top_right: line::THICK.top_right,
bottom_left: line::THICK.bottom_left,
bottom_right: line::THICK.bottom_right,
vertical_left: line::THICK.vertical,
vertical_right: line::THICK.vertical,
horizontal_top: line::THICK.horizontal,
horizontal_bottom: line::THICK.horizontal,
};
pub const LIGHT_DOUBLE_DASHED: Set = from_line_set(line::LIGHT_DOUBLE_DASHED);
pub const HEAVY_DOUBLE_DASHED: Set = from_line_set(line::HEAVY_DOUBLE_DASHED);
pub const LIGHT_TRIPLE_DASHED: Set = from_line_set(line::LIGHT_TRIPLE_DASHED);
pub const HEAVY_TRIPLE_DASHED: Set = from_line_set(line::HEAVY_TRIPLE_DASHED);
pub const LIGHT_QUADRUPLE_DASHED: Set = from_line_set(line::LIGHT_QUADRUPLE_DASHED);
pub const HEAVY_QUADRUPLE_DASHED: Set = from_line_set(line::HEAVY_QUADRUPLE_DASHED);
pub const QUADRANT_TOP_LEFT: &str = "▘";
pub const QUADRANT_TOP_RIGHT: &str = "▝";
pub const QUADRANT_BOTTOM_LEFT: &str = "▖";
pub const QUADRANT_BOTTOM_RIGHT: &str = "▗";
pub const QUADRANT_TOP_HALF: &str = "▀";
pub const QUADRANT_BOTTOM_HALF: &str = "▄";
pub const QUADRANT_LEFT_HALF: &str = "▌";
pub const QUADRANT_RIGHT_HALF: &str = "▐";
pub const QUADRANT_TOP_LEFT_BOTTOM_LEFT_BOTTOM_RIGHT: &str = "▙";
pub const QUADRANT_TOP_LEFT_TOP_RIGHT_BOTTOM_LEFT: &str = "▛";
pub const QUADRANT_TOP_LEFT_TOP_RIGHT_BOTTOM_RIGHT: &str = "▜";
pub const QUADRANT_TOP_RIGHT_BOTTOM_LEFT_BOTTOM_RIGHT: &str = "▟";
pub const QUADRANT_TOP_LEFT_BOTTOM_RIGHT: &str = "▚";
pub const QUADRANT_TOP_RIGHT_BOTTOM_LEFT: &str = "▞";
pub const QUADRANT_BLOCK: &str = "█";
pub const QUADRANT_OUTSIDE: Set = Set {
top_left: QUADRANT_TOP_LEFT_TOP_RIGHT_BOTTOM_LEFT,
top_right: QUADRANT_TOP_LEFT_TOP_RIGHT_BOTTOM_RIGHT,
bottom_left: QUADRANT_TOP_LEFT_BOTTOM_LEFT_BOTTOM_RIGHT,
bottom_right: QUADRANT_TOP_RIGHT_BOTTOM_LEFT_BOTTOM_RIGHT,
vertical_left: QUADRANT_LEFT_HALF,
vertical_right: QUADRANT_RIGHT_HALF,
horizontal_top: QUADRANT_TOP_HALF,
horizontal_bottom: QUADRANT_BOTTOM_HALF,
};
pub const QUADRANT_INSIDE: Set = Set {
top_right: QUADRANT_BOTTOM_LEFT,
top_left: QUADRANT_BOTTOM_RIGHT,
bottom_right: QUADRANT_TOP_LEFT,
bottom_left: QUADRANT_TOP_RIGHT,
vertical_left: QUADRANT_RIGHT_HALF,
vertical_right: QUADRANT_LEFT_HALF,
horizontal_top: QUADRANT_BOTTOM_HALF,
horizontal_bottom: QUADRANT_TOP_HALF,
};
pub const ONE_EIGHTH_TOP_EIGHT: &str = "▔";
pub const ONE_EIGHTH_BOTTOM_EIGHT: &str = "▁";
pub const ONE_EIGHTH_LEFT_EIGHT: &str = "▏";
pub const ONE_EIGHTH_RIGHT_EIGHT: &str = "▕";
#[expect(clippy::doc_markdown)]
pub const ONE_EIGHTH_WIDE: Set = Set {
top_right: ONE_EIGHTH_BOTTOM_EIGHT,
top_left: ONE_EIGHTH_BOTTOM_EIGHT,
bottom_right: ONE_EIGHTH_TOP_EIGHT,
bottom_left: ONE_EIGHTH_TOP_EIGHT,
vertical_left: ONE_EIGHTH_LEFT_EIGHT,
vertical_right: ONE_EIGHTH_RIGHT_EIGHT,
horizontal_top: ONE_EIGHTH_BOTTOM_EIGHT,
horizontal_bottom: ONE_EIGHTH_TOP_EIGHT,
};
#[expect(clippy::doc_markdown)]
pub const ONE_EIGHTH_TALL: Set = Set {
top_right: ONE_EIGHTH_LEFT_EIGHT,
top_left: ONE_EIGHTH_RIGHT_EIGHT,
bottom_right: ONE_EIGHTH_LEFT_EIGHT,
bottom_left: ONE_EIGHTH_RIGHT_EIGHT,
vertical_left: ONE_EIGHTH_RIGHT_EIGHT,
vertical_right: ONE_EIGHTH_LEFT_EIGHT,
horizontal_top: ONE_EIGHTH_TOP_EIGHT,
horizontal_bottom: ONE_EIGHTH_BOTTOM_EIGHT,
};
pub const PROPORTIONAL_WIDE: Set = Set {
top_right: QUADRANT_BOTTOM_HALF,
top_left: QUADRANT_BOTTOM_HALF,
bottom_right: QUADRANT_TOP_HALF,
bottom_left: QUADRANT_TOP_HALF,
vertical_left: QUADRANT_BLOCK,
vertical_right: QUADRANT_BLOCK,
horizontal_top: QUADRANT_BOTTOM_HALF,
horizontal_bottom: QUADRANT_TOP_HALF,
};
pub const PROPORTIONAL_TALL: Set = Set {
top_right: QUADRANT_BLOCK,
top_left: QUADRANT_BLOCK,
bottom_right: QUADRANT_BLOCK,
bottom_left: QUADRANT_BLOCK,
vertical_left: QUADRANT_BLOCK,
vertical_right: QUADRANT_BLOCK,
horizontal_top: QUADRANT_TOP_HALF,
horizontal_bottom: QUADRANT_BOTTOM_HALF,
};
pub const FULL: Set = Set {
top_left: block::FULL,
top_right: block::FULL,
bottom_left: block::FULL,
bottom_right: block::FULL,
vertical_left: block::FULL,
vertical_right: block::FULL,
horizontal_top: block::FULL,
horizontal_bottom: block::FULL,
};
pub const EMPTY: Set = Set {
top_left: " ",
top_right: " ",
bottom_left: " ",
bottom_right: " ",
vertical_left: " ",
vertical_right: " ",
horizontal_top: " ",
horizontal_bottom: " ",
};
#[cfg(test)]
mod tests {
use alloc::format;
use alloc::string::String;
use indoc::{formatdoc, indoc};
use super::*;
#[test]
fn default() {
assert_eq!(Set::default(), PLAIN);
}
fn render(set: Set) -> String {
formatdoc!(
"░░░░░░
░{}{}{}{}░
░{}░░{}░
░{}░░{}░
░{}{}{}{}░
░░░░░░",
set.top_left,
set.horizontal_top,
set.horizontal_top,
set.top_right,
set.vertical_left,
set.vertical_right,
set.vertical_left,
set.vertical_right,
set.bottom_left,
set.horizontal_bottom,
set.horizontal_bottom,
set.bottom_right
)
}
#[test]
fn border_set_from_line_set() {
let custom_line_set = line::Set {
top_left: "a",
top_right: "b",
bottom_left: "c",
bottom_right: "d",
vertical: "e",
horizontal: "f",
vertical_left: "g",
vertical_right: "h",
horizontal_down: "i",
horizontal_up: "j",
cross: "k",
};
let border_set = from_line_set(custom_line_set);
assert_eq!(
border_set,
Set {
top_left: "a",
top_right: "b",
bottom_left: "c",
bottom_right: "d",
vertical_left: "e",
vertical_right: "e",
horizontal_bottom: "f",
horizontal_top: "f",
}
);
}
#[test]
fn plain() {
assert_eq!(
render(PLAIN),
indoc!(
"░░░░░░
░┌──┐░
░│░░│░
░│░░│░
░└──┘░
░░░░░░"
)
);
}
#[test]
fn rounded() {
assert_eq!(
render(ROUNDED),
indoc!(
"░░░░░░
░╭──╮░
░│░░│░
░│░░│░
░╰──╯░
░░░░░░"
)
);
}
#[test]
fn double() {
assert_eq!(
render(DOUBLE),
indoc!(
"░░░░░░
░╔══╗░
░║░░║░
░║░░║░
░╚══╝░
░░░░░░"
)
);
}
#[test]
fn thick() {
assert_eq!(
render(THICK),
indoc!(
"░░░░░░
░┏━━┓░
░┃░░┃░
░┃░░┃░
░┗━━┛░
░░░░░░"
)
);
}
#[test]
fn light_double_dashed() {
assert_eq!(
render(LIGHT_DOUBLE_DASHED),
indoc!(
"░░░░░░
░┌╌╌┐░
░╎░░╎░
░╎░░╎░
░└╌╌┘░
░░░░░░"
)
);
}
#[test]
fn heavy_double_dashed() {
assert_eq!(
render(HEAVY_DOUBLE_DASHED),
indoc!(
"░░░░░░
░┏╍╍┓░
░╏░░╏░
░╏░░╏░
░┗╍╍┛░
░░░░░░"
)
);
}
#[test]
fn light_triple_dashed() {
assert_eq!(
render(LIGHT_TRIPLE_DASHED),
indoc!(
"░░░░░░
░┌┄┄┐░
░┆░░┆░
░┆░░┆░
░└┄┄┘░
░░░░░░"
)
);
}
#[test]
fn heavy_triple_dashed() {
assert_eq!(
render(HEAVY_TRIPLE_DASHED),
indoc!(
"░░░░░░
░┏┅┅┓░
░┇░░┇░
░┇░░┇░
░┗┅┅┛░
░░░░░░"
)
);
}
#[test]
fn light_quadruple_dashed() {
assert_eq!(
render(LIGHT_QUADRUPLE_DASHED),
indoc!(
"░░░░░░
░┌┈┈┐░
░┊░░┊░
░┊░░┊░
░└┈┈┘░
░░░░░░"
)
);
}
#[test]
fn heavy_quadruple_dashed() {
assert_eq!(
render(HEAVY_QUADRUPLE_DASHED),
indoc!(
"░░░░░░
░┏┉┉┓░
░┋░░┋░
░┋░░┋░
░┗┉┉┛░
░░░░░░"
)
);
}
#[test]
fn quadrant_outside() {
assert_eq!(
render(QUADRANT_OUTSIDE),
indoc!(
"░░░░░░
░▛▀▀▜░
░▌░░▐░
░▌░░▐░
░▙▄▄▟░
░░░░░░"
)
);
}
#[test]
fn quadrant_inside() {
assert_eq!(
render(QUADRANT_INSIDE),
indoc!(
"░░░░░░
░▗▄▄▖░
░▐░░▌░
░▐░░▌░
░▝▀▀▘░
░░░░░░"
)
);
}
#[test]
fn one_eighth_wide() {
assert_eq!(
render(ONE_EIGHTH_WIDE),
indoc!(
"░░░░░░
░▁▁▁▁░
░▏░░▕░
░▏░░▕░
░▔▔▔▔░
░░░░░░"
)
);
}
#[test]
fn one_eighth_tall() {
assert_eq!(
render(ONE_EIGHTH_TALL),
indoc!(
"░░░░░░
░▕▔▔▏░
░▕░░▏░
░▕░░▏░
░▕▁▁▏░
░░░░░░"
)
);
}
#[test]
fn proportional_wide() {
assert_eq!(
render(PROPORTIONAL_WIDE),
indoc!(
"░░░░░░
░▄▄▄▄░
░█░░█░
░█░░█░
░▀▀▀▀░
░░░░░░"
)
);
}
#[test]
fn proportional_tall() {
assert_eq!(
render(PROPORTIONAL_TALL),
indoc!(
"░░░░░░
░█▀▀█░
░█░░█░
░█░░█░
░█▄▄█░
░░░░░░"
)
);
}
#[test]
fn full() {
assert_eq!(
render(FULL),
indoc!(
"░░░░░░
░████░
░█░░█░
░█░░█░
░████░
░░░░░░"
)
);
}
#[test]
fn empty() {
assert_eq!(
render(EMPTY),
indoc!(
"░░░░░░
░ ░
░ ░░ ░
░ ░░ ░
░ ░
░░░░░░"
)
);
}
}