trace-game 1.0.2

A terminal typing game written in rust, local multiplayer support planned
Documentation
use crate::add_to_commands;
use crate::generate_all_chars;
use crate::get_app_path;
use crate::windows::create_main_menu_window;
use crate::State;
use crate::Window;
use crate::WindowCommand;
use crossterm::event::KeyCode;
use std::collections::HashMap;
use std::rc::Rc;
use tui::backend::Backend;
use tui::layout::Alignment;
use tui::style::Color;
use tui::style::Style;
use tui::text::Span;
use tui::text::Spans;
use tui::widgets::Paragraph;
use tui::Frame;

fn user_window<B: 'static + Backend>(state: Rc<State>) -> Box<dyn Fn(&mut Frame<B>)> {
    Box::new(move |f| {
        let paragraph = Paragraph::new(vec![Spans::from(vec![
            Span::from("Please write your username:\n"),
            Span::styled(
                state.user_name.to_string(),
                Style::default().fg(Color::Yellow),
            ),
        ])])
        .alignment(Alignment::Center);
        f.render_widget(paragraph, f.size());
    })
}

fn handle_char_press<B: 'static + Backend>(
    c: char,
) -> Box<dyn Fn(&mut State) -> Option<Window<B>>> {
    Box::new(move |state: &mut State| {
        state.user_name.push(c);
        create_user_window(state)
    })
}

pub fn create_user_window<B: 'static + Backend>(_: &mut State) -> Option<Window<B>> {
    let chars = generate_all_chars();
    let mut commands = HashMap::new();
    add_to_commands(&mut commands, &chars, Box::new(handle_char_press));

    fn handle_backspace_press<B: 'static + Backend>(state: &mut State) -> Option<Window<B>> {
        state.user_name.pop();
        create_user_window(state)
    }
    commands.insert(
        KeyCode::Backspace,
        WindowCommand {
            activator_key: KeyCode::Backspace,
            action: Box::new(handle_backspace_press),
        },
    );
    commands.insert(
        KeyCode::Enter,
        WindowCommand {
            activator_key: KeyCode::Enter,
            action: Box::new(|state| {
                let path = get_app_path(".user");
                match std::fs::write(path, state.user_name.to_string()) {
                    Ok(_) => create_main_menu_window(state),
                    Err(_) => create_user_window(state),
                }
            }),
        },
    );

    Some(Window {
        ui: user_window,
        commands,
    })
}