cli_printer 0.2.0

A library for create a cli apps
Documentation
use crossterm::{execute, style::Print};

use crate::core::{
    interfaces::{Widget, WidgetChild},
    utils::{self, Action, RenderWidget},
};

type AfterCb<T> = Box<dyn FnMut(&mut TextBlockData, T) -> Action>;
type BeforeCb<T> = Box<dyn FnMut(&mut TextBlockData, T) -> RenderWidget>;
pub struct TextBlock<T> {
    cb_after: AfterCb<T>,
    cb_before: BeforeCb<T>,
    local_state: TextBlockData,
}

pub struct TextBlockData {
    pub text: String,
}

impl<T: Clone> Widget for TextBlock<T> {
    fn render(&mut self, stdout: &mut std::io::Stdout) -> std::io::Result<()> {
        execute!(stdout, Print(&self.local_state.text))?;
        Ok(())
    }
}

impl<T: Clone> WidgetChild<T> for TextBlock<T> {
    fn after_render(&mut self, global_state: T) -> utils::Action {
        (self.cb_after)(&mut self.local_state, global_state)
    }

    fn before_render(&mut self, global_state: T) -> RenderWidget {
        (self.cb_before)(&mut self.local_state, global_state)
    }
}

impl<T: Clone> TextBlock<T> {
    pub fn new(text: &str) -> Self {
        Self {
            cb_after: Box::new(|_, _| Action::Next),
            cb_before: Box::new(|_, _| RenderWidget::Yes),
            local_state: TextBlockData {
                text: text.to_owned(),
            },
        }
    }
    pub fn after(&mut self, cb: impl FnMut(&mut TextBlockData, T) -> Action + 'static) {
        self.cb_after = Box::new(cb)
    }
    pub fn before(&mut self, cb: impl FnMut(&mut TextBlockData, T) -> RenderWidget + 'static) {
        self.cb_before = Box::new(cb)
    }
}