gotl 0.1.0

Parse and view Go test logs
Documentation
use std::time::Duration;

use anyhow::{Context, Result};
use clap::Parser;
use gotl::{
    PostEventAction,
    screen::{Screen, tests_screen::TestsScreen},
};
use ratatui::crossterm::event;

#[derive(Parser, Debug)]
struct Args {
    #[arg(long, help = "Hide skipped test cases on startup")]
    hide_skipped: bool,
    #[arg(long, help = "Hide failed test cases on startup")]
    hide_failed: bool,
    #[arg(long, help = "Hide passed test cases on startup")]
    hide_passed: bool,
    #[arg(long, default_value = "./...", help = "Packages to test")]
    packages: String,
    #[arg(last = true, help = "Arguments passed to `go test` command")]
    additional_args: Vec<String>,
}

#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<()> {
    let args = Args::parse();

    let mut terminal = ratatui::init();

    let mut tests_screen = TestsScreen::new()
        .with_packages_path(args.packages)
        .with_show_skipped(!args.hide_skipped)
        .with_show_failed(!args.hide_failed)
        .with_show_passed(!args.hide_passed)
        .with_additional_args(args.additional_args);

    tests_screen
        .start_loading_packages()
        .context("Failed to load test packages")?;

    let mut screen_stack: Vec<Screen> = vec![Box::new(tests_screen).into()];

    while let Some(current_screen) = screen_stack.last_mut() {
        let updated = current_screen
            .update()
            .await
            .context("Failed to update screen")?;

        terminal
            .draw(|frame| current_screen.render(frame))
            .context("Failed to render screen")?;

        let poll_duration = if updated { 0 } else { 100 };
        if event::poll(Duration::from_millis(poll_duration))? {
            match current_screen.handle_event(event::read().context("failed to read next event")?) {
                Ok(Some(PostEventAction::PopScreen)) => {
                    screen_stack.pop();
                }
                Ok(Some(PostEventAction::PushScreen(screen))) => {
                    screen_stack.push(screen);
                }
                Ok(None) => (),
                // TODO: Introduce an error popup screen
                Err(_) => (),
            }
        }
    }
    ratatui::restore();
    Ok(())
}