Rustea

An easy-to-use TUI crate for Rust, based off of the Elm architecture. This is a re-implementation of Go's Tea, created by TJ Holowaychuk.

Features

https://user-images.githubusercontent.com/103537080/163859892-3e9364ba-395d-4f4a-8c8c-984b8bea2abf.mov

Installation and Docs

Install by putting rustea = "0.1.0" in your Cargo.toml dependencies.

Docs can be found on docs.rs.

Quickstart

An example demonstrating a website length checker, with batched asynchronous commands.

```rust use crossterm::event::KeyModifiers; use rustea::{ command, crossterm::event::{KeyCode, KeyEvent}, view_helper::input::Input, App, Command, Message, };

struct Model { urlinput: Input, websitelengths: Vec, }

impl App for Model { fn update(&mut self, msg: Message) -> Option { if let Some(keyevent) = msg.downcastref::() { if let KeyModifiers::CONTROL = keyevent.modifiers { if let KeyCode::Char('c') = keyevent.code { return Some(Box::new(command::quit)); } }

        match key_event.code {
            KeyCode::Enter => {
                let url = self.url_input.buffer();
                self.url_input.clear();

                // make 3 requests to demonstrate command batching
                let commands = vec![
                    make_request_command(url.clone()),
                    make_request_command(url.clone()),
                    make_request_command(url),
                ];
                return Some(command::batch(commands));
            }
            _ => self.url_input.on_key_event(*key_event),
        }
    } else if let Some(len) = msg.downcast_ref::<WebsiteLengthMessage>() {
        self.website_lengths.push(len.0);
    }

    None
}

fn view(&self) -> String {
    let mut out = format!(
        "Website URL (press enter when done): {}",
        self.url_input.buffer()
    );
    for (i, len) in self.website_lengths.iter().enumerate() {
        out.push_str(&format!("\nHit {} length: {}", i, len));
    }

    out
}

}

struct WebsiteLengthMessage(usize);

fn makerequestcommand(url: String) -> Command { Box::new(move || { // It's okay to block since commands are multi threaded let websitelen = reqwest::blocking::get(url).unwrap().bytes().unwrap().len(); Some(Box::new(WebsiteLengthMessage(websitelen))) }) }

fn main() { rustea::run(Model { urlinput: Input::new(), websitelengths: Vec::new(), }) .unwrap(); }

```

More Examples

For more examples, see the examples directory.