pub mod terminal {
pub fn new_term() -> console::Term {
console::Term::stdout()
}
pub fn clear() {
let _ = std::process::Command::new("clear").status();
}
pub fn write(term: &console::Term, item: &dyn std::fmt::Display) {
let _ = term.write_str(format!("{}", item).as_str());
}
pub fn getch(term: &console::Term) -> char {
term.read_char().unwrap()
}
pub fn getche(term: &console::Term, ch: Option<char>) -> char {
let new_ch = term.read_char().unwrap();
let _ = match ch {
Some(c) => {
if new_ch != '\n' {
term.write_str(c.to_string().as_str())
} else {
term.write_str(" ".to_string().as_str())
}
}
None => term.write_str(new_ch.to_string().as_str()),
};
return new_ch;
}
pub fn bulk_getche(term: &console::Term, ch: Option<char>, n: u8) -> Vec<char> {
let mut chars: Vec<char> = Vec::new();
for _ in 0..n {
let x = getche(term, ch);
if x == '\n' {
break;
} else {
chars.push(x);
}
}
chars
}
pub fn getk(term: &console::Term) -> console::Key {
term.read_key().unwrap()
}
pub fn get_string(term: &console::Term, ch: Option<char>, n: u8) -> String {
use console::Key;
let mut charlist: Vec<char> = Vec::new();
let mut index: u8 = 0;
while index < n + 1 {
let x = getk(term);
match x {
Key::Enter => break,
Key::Char(s) => {
if index == n {
} else if index == charlist.len() as u8 {
charlist.push(s);
let _ = term.write_str(
format!(
"{}",
match ch {
Some(c) => c,
None => s,
}
)
.as_str(),
);
index += 1;
} else {
charlist[index as usize] = s;
let _ = term.write_str(
format!(
"{}",
match ch {
Some(c) => c,
None => s,
}
)
.as_str(),
);
index += 1;
}
}
Key::ArrowLeft => {
if index != 0 {
let _ = term.write_str("\x1b[D");
index -= 1;
}
}
Key::ArrowRight => {
if index != charlist.len() as u8 {
let _ = term.write_str("\x1b[C");
index += 1;
}
}
Key::Backspace => {
if index == charlist.len() as u8 && index != 0 {
charlist.pop();
let _ = term.write_str("\x1b[D \x1b[D");
index -= 1;
}
}
_ => (),
}
}
charlist.iter().fold(String::new(), |x, y| {
let mut z = x;
z.push(*y);
z
})
}
pub fn menu(term: &console::Term, items: Vec<&dyn core::fmt::Display>) -> u32 {
use console::Key;
let mut i = 0;
let mut new_i = 0;
for item in &items {
let _ = term.write_str(format!("{}\n", item).as_str());
}
for _ in &items {
let _ = term.write_str("\x1b[A\r");
}
loop {
let _ = term.write_str(
format!(
"\r\x1b[2K\x1b[38;2;0;0;0m\x1b[48;2;255;255;255m\
{}\
\x1b[m\x1b[?25l\
",
items[i]
)
.as_str(),
);
let key = getk(term);
match key {
Key::Enter => {
break;
}
Key::ArrowUp => {
if i != 0 {
new_i -= 1;
}
}
Key::ArrowDown => {
if i < items.len() - 1 {
new_i += 1;
}
}
_ => (),
}
if new_i != i {
let _ = term.write_str("\x1b[2K\r");
let _ = term.write_str(format!("{}", items[i]).as_str());
for _ in i..items.len() {
let _ = term.write_str("\x1b[B");
}
for _ in new_i..items.len() {
let _ = term.write_str("\x1b[A");
}
}
i = new_i;
}
for _ in 0..(items.len() - i) {
let _ = term.write_str("\x1b[B\x1b[2K\r");
}
for _ in &items {
let _ = term.write_str("\x1b[A\x1b[2K\r");
}
let _ = term.write_str("\x1b[?25h");
i as u32
}
}
pub mod linear_algebra {
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
pub struct Matrix<const H: usize, const W: usize> {
data: [[f32; W]; H],
}
impl<const H: usize, const W: usize> Matrix<H,W> {
pub fn new(input: [[f32;W];H])->Matrix<H,W> {
Matrix {
data: input
}
}
}
impl<const H: usize, const W: usize> std::ops::Index<(usize, usize)> for Matrix<H, W> {
type Output = f32;
fn index(&self, (x,y): (usize, usize)) -> &Self::Output {
return &self.data[y][x];
}
}
impl<const H: usize, const W: usize> std::ops::Add for Matrix<H, W> {
type Output = Matrix<H, W>;
fn add(self, rhs: Self) -> Self::Output {
let mut result = [[0.0; W]; H];
for h in 0..H {
for w in 0..W {
result[h][w] = self[(w,h)] + rhs[(w,h)];
}
}
Matrix { data: result }
}
}
}