99 lines
2.5 KiB
Rust
99 lines
2.5 KiB
Rust
use core::fmt;
|
|
|
|
use binrw::{BinRead, BinWrite};
|
|
use substring::Substring;
|
|
|
|
|
|
const SYMBOL_PARTS: &str = include_str!("symbol_parts.txt");
|
|
const SYMBOL_PART_WIDTH: usize = 6;
|
|
const SYMBOL_PART_HEIGTH: usize = 3;
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, BinRead, BinWrite)]
|
|
pub struct Symbol {
|
|
pub id: u32,
|
|
}
|
|
|
|
impl fmt::Display for Symbol {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "{}", get_symbol(self.id as usize).unwrap())
|
|
}
|
|
}
|
|
|
|
fn get_symbol(id: usize) -> Option<String> {
|
|
let (top_left, top_right, btm_left, btm_right) = symbol_part_ids(id)?;
|
|
get_symbol_with_parts(top_left, top_right, btm_left, btm_right)
|
|
}
|
|
|
|
fn symbol_part_ids(id: usize) -> Option<(usize, usize, usize, usize)> {
|
|
let ids = match id {
|
|
0 => (0, 1, 3, 2),
|
|
1 => (4, 4, 7, 7),
|
|
2 => (9, 9, 13, 2),
|
|
3 => (15, 16, 9, 9),
|
|
4 => (4, 9, 4, 9),
|
|
5 => (15, 12, 3, 9),
|
|
6 => (5, 5, 9, 12),
|
|
7 => (12, 9, 15, 15),
|
|
8 => (7, 9, 12, 8),
|
|
9 => (12, 12, 9, 9),
|
|
10 => (14, 7, 14, 7),
|
|
11 => (8, 8, 13, 13),
|
|
12 => (2, 3, 2, 3),
|
|
13 => (10, 7, 7, 12),
|
|
14 => (7, 7, 10, 12),
|
|
15 => (15, 15, 15, 15),
|
|
16 => (4, 4, 4, 4),
|
|
17 => (11, 10, 11, 10),
|
|
18 => (12, 8, 12, 8),
|
|
19 => (6, 6, 11, 10),
|
|
20 => (12, 9, 11, 10),
|
|
_ => return None,
|
|
};
|
|
|
|
Some(ids)
|
|
}
|
|
|
|
fn get_symbol_with_parts(
|
|
top_left: usize,
|
|
top_right: usize,
|
|
btm_left: usize,
|
|
btm_right: usize,
|
|
) -> Option<String> {
|
|
if top_left > 16 || top_right > 16 || btm_left > 16 || btm_right > 16 {
|
|
return None;
|
|
}
|
|
|
|
let top_left = get_symbol_part(top_left);
|
|
let top_right = get_symbol_part(top_right);
|
|
let btm_left = get_symbol_part(btm_left);
|
|
let btm_right = get_symbol_part(btm_right);
|
|
|
|
let top = top_left
|
|
.lines()
|
|
.zip(top_right.lines())
|
|
.map(|(left, right)| format!("{} {}", left, right));
|
|
|
|
let bottom = btm_left
|
|
.lines()
|
|
.zip(btm_right.lines())
|
|
.map(|(left, right)| format!("{} {}", left, right));
|
|
|
|
const EMPTY_LINE: &str = " ";
|
|
|
|
let symbol = top
|
|
.chain([EMPTY_LINE.to_string()].into_iter())
|
|
.chain(bottom)
|
|
.collect::<Vec<_>>()
|
|
.join("\n");
|
|
|
|
Some(symbol)
|
|
}
|
|
|
|
fn get_symbol_part(idx: usize) -> &'static str {
|
|
const SYMBOL_PART_SIZE: usize = SYMBOL_PART_WIDTH * SYMBOL_PART_HEIGTH + 2;
|
|
let start = (SYMBOL_PART_SIZE + 2) * idx;
|
|
let end = start + SYMBOL_PART_SIZE;
|
|
SYMBOL_PARTS.substring(start, end)
|
|
}
|