Building a Terminal TODO App in Rust

Project Overview

The Terminal TODO App is a command-line task manager built with Rust. It utilizes the tui and crossterm crates to create an interactive terminal user interface.

Key Features

Dual list management (TODO and DONE l…


This content originally appeared on DEV Community and was authored by Tramposo

Project Overview

The Terminal TODO App is a command-line task manager built with Rust. It utilizes the tui and crossterm crates to create an interactive terminal user interface.

Key Features

  • Dual list management (TODO and DONE lists)
  • Interactive navigation
  • Task editing and deletion
  • Data persistence
  • Vim-inspired keybindings

Technical Breakdown

1. State Management

The app's state is managed through a central App struct:

struct App {
    todos: Vec<String>,
    done: Vec<String>,
    input: String,
    input_mode: InputMode,
    todo_list_state: ListState,
    done_list_state: ListState,
    editing_index: Option<usize>,
}

This structure captures all the necessary data for the application, including the task lists, current input, and UI state.

2. User Input Handling

User input is processed in the main event loop:

fn run_app<B: tui::backend::Backend>(terminal: &mut Terminal<B>, app: &mut App) -> io::Result<()> {
    loop {
        terminal.draw(|f| ui(f, app))?;

        if let Event::Key(key) = event::read()? {
            match app.input_mode {
                InputMode::Normal => match key.code {
                    // Handle normal mode inputs
                },
                InputMode::Editing => match key.code {
                    // Handle editing mode inputs
                },
                InputMode::EditingExisting => match key.code {
                    // Handle existing item editing inputs
                },
            }
        }
    }
}

This pattern allows for different behaviors based on the current input mode.

3. Rendering the UI

The terminal UI is rendered using the tui crate:

fn ui<B: tui::backend::Backend>(f: &mut Frame<B>, app: &App) {
    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .margin(2)
        .constraints([
            Constraint::Length(3),
            Constraint::Min(0),
            Constraint::Length(3),
        ])
        .split(f.size());

    // Render TODO and DONE lists
    let lists = Layout::default()
        .direction(Direction::Horizontal)
        .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
        .split(chunks[1]);

    let todo_items: Vec<ListItem> = app.todos.iter().map(|i| ListItem::new(i.as_ref())).collect();
    let todo_list = List::new(todo_items)
        .block(Block::default().borders(Borders::ALL).title("Todo"));

    f.render_stateful_widget(todo_list, lists[0], &mut app.todo_list_state);

    // Similar rendering for DONE list...
}

This function demonstrates how to create a layout and render widgets like lists and input fields.

4. Data Persistence

Task persistence is implemented using simple file I/O:

impl App {
    pub fn save_to_file(&self, filename: &str) -> io::Result<()> {
        let mut file = OpenOptions::new()
            .write(true)
            .create(true)
            .truncate(true)
            .open(filename)?;

        writeln!(file, "[TODO]")?;
        for item in &self.todos {
            writeln!(file, "{}", item)?;
        }

        writeln!(file, "[DONE]")?;
        for item in &self.done {
            writeln!(file, "{}", item)?;
        }

        Ok(())
    }

    pub fn load_from_file(filename: &str) -> io::Result<Self> {
        // Implementation of file loading...
    }
}

This approach is straightforward to save and load the application state between sessions.


This content originally appeared on DEV Community and was authored by Tramposo


Print Share Comment Cite Upload Translate Updates
APA

Tramposo | Sciencx (2024-09-19T00:58:48+00:00) Building a Terminal TODO App in Rust. Retrieved from https://www.scien.cx/2024/09/19/building-a-terminal-todo-app-in-rust/

MLA
" » Building a Terminal TODO App in Rust." Tramposo | Sciencx - Thursday September 19, 2024, https://www.scien.cx/2024/09/19/building-a-terminal-todo-app-in-rust/
HARVARD
Tramposo | Sciencx Thursday September 19, 2024 » Building a Terminal TODO App in Rust., viewed ,<https://www.scien.cx/2024/09/19/building-a-terminal-todo-app-in-rust/>
VANCOUVER
Tramposo | Sciencx - » Building a Terminal TODO App in Rust. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/09/19/building-a-terminal-todo-app-in-rust/
CHICAGO
" » Building a Terminal TODO App in Rust." Tramposo | Sciencx - Accessed . https://www.scien.cx/2024/09/19/building-a-terminal-todo-app-in-rust/
IEEE
" » Building a Terminal TODO App in Rust." Tramposo | Sciencx [Online]. Available: https://www.scien.cx/2024/09/19/building-a-terminal-todo-app-in-rust/. [Accessed: ]
rf:citation
» Building a Terminal TODO App in Rust | Tramposo | Sciencx | https://www.scien.cx/2024/09/19/building-a-terminal-todo-app-in-rust/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.