rtlibs-tui 0.1.4

rtools library: ratatui widgets
Documentation
use crossterm::event::KeyCode;
use crossterm::event::KeyModifiers;
use time::Date;

use crate::widgets::InputNumberEvent;
use crate::widgets::KeyEventHandler;
use crate::Result;

use super::InputDateFocus;
use super::InputDateState;

pub enum InputDateEvent
{
    NotHandled,
    Handled,
    Change(Option<Date>),
    Confirm(Date),
    Cancel(),
}

impl InputDateState
{
    pub(crate) fn handle_key_event_day(
        &mut self,
        code: KeyCode,
        modifiers: KeyModifiers,
    ) -> Result<InputDateEvent>
    {
        let handled = InputDateEvent::Handled;

        let response = match self
            .input_day
            .handle_key_event(
                code, modifiers,
            )?
        {
            InputNumberEvent::NotHandled => match code
            {
                KeyCode::Tab =>
                {
                    self.input_mode = InputDateFocus::Month;
                    handled
                }
                KeyCode::BackTab =>
                {
                    self.input_mode = InputDateFocus::Year;
                    handled
                }
                _ => InputDateEvent::NotHandled,
            },
            InputNumberEvent::Handled => handled,
            InputNumberEvent::Change(str, _) =>
            {
                if str
                    .chars()
                    .count()
                    >= 2
                {
                    self.input_mode = InputDateFocus::Month;
                }
                InputDateEvent::Change(self.input())
            }
            InputNumberEvent::Confirm(_, _) =>
            {
                if let Some(date) = self.input()
                {
                    InputDateEvent::Confirm(date)
                }
                else
                {
                    InputDateEvent::Handled
                }
            }
            InputNumberEvent::Cancel() => InputDateEvent::Cancel(),
        };

        Ok(response)
    }

    fn handle_key_event_month(
        &mut self,
        code: KeyCode,
        modifiers: KeyModifiers,
    ) -> Result<InputDateEvent>
    {
        let handled = InputDateEvent::Handled;

        let response = match self
            .input_month
            .handle_key_event(
                code, modifiers,
            )?
        {
            InputNumberEvent::NotHandled => match code
            {
                KeyCode::Tab =>
                {
                    self.input_mode = InputDateFocus::Year;
                    handled
                }
                KeyCode::BackTab =>
                {
                    self.input_mode = InputDateFocus::Day;
                    handled
                }
                _ => InputDateEvent::NotHandled,
            },
            InputNumberEvent::Handled => handled,
            InputNumberEvent::Change(str, _) =>
            {
                if str
                    .chars()
                    .count()
                    >= 2
                {
                    self.input_mode = InputDateFocus::Year;
                }
                InputDateEvent::Change(self.input())
            }
            InputNumberEvent::Confirm(_, _) =>
            {
                if let Some(date) = self.input()
                {
                    InputDateEvent::Confirm(date)
                }
                else
                {
                    InputDateEvent::Handled
                }
            }
            InputNumberEvent::Cancel() => InputDateEvent::Cancel(),
        };

        Ok(response)
    }

    fn handle_key_event_year(
        &mut self,
        code: KeyCode,
        modifiers: KeyModifiers,
    ) -> Result<InputDateEvent>
    {
        let handled = InputDateEvent::Handled;

        let response = match self
            .input_year
            .handle_key_event(
                code, modifiers,
            )?
        {
            InputNumberEvent::NotHandled => match code
            {
                KeyCode::Tab =>
                {
                    self.input_mode = InputDateFocus::Day;
                    handled
                }
                KeyCode::BackTab =>
                {
                    self.input_mode = InputDateFocus::Month;
                    handled
                }
                _ => InputDateEvent::NotHandled,
            },
            InputNumberEvent::Handled => handled,
            InputNumberEvent::Change(_, _) => InputDateEvent::Change(self.input()),
            InputNumberEvent::Confirm(_, _) =>
            {
                if let Some(date) = self.input()
                {
                    InputDateEvent::Confirm(date)
                }
                else
                {
                    InputDateEvent::Handled
                }
            }
            InputNumberEvent::Cancel() => InputDateEvent::Cancel(),
        };

        Ok(response)
    }
}

impl KeyEventHandler<'_, InputDateEvent> for InputDateState
{
    fn handle_key_event(
        &mut self,
        code: KeyCode,
        modifiers: KeyModifiers,
    ) -> Result<InputDateEvent>
    {
        let response = match self.input_mode
        {
            InputDateFocus::Day => self.handle_key_event_day(
                code, modifiers,
            )?,
            InputDateFocus::Month => self.handle_key_event_month(
                code, modifiers,
            )?,
            InputDateFocus::Year => self.handle_key_event_year(
                code, modifiers,
            )?,
        };

        Ok(response)
    }
}