mod app_events;
mod app_render;
mod state;
use anyhow::{bail, Result};
use regex::bytes::Regex;
use state::HelpTextState;
pub use state::{AppListState, AppState, AppUiState};
use crate::model::{PrintableStyle, ReplacementCriteria};
use crate::rg::de::{RgMessage, Stats};
use crate::ui::line::Item;
const HELP_TEXT: &str = include_str!("../../../doc/rgr.1.template");
pub struct App {
pub state: AppState,
capture_pattern: Option<Regex>,
rg_cmdline: String,
stats: Stats,
list: Vec<Item>,
list_state: AppListState,
ui_state: AppUiState,
help_text_state: HelpTextState,
printable_style: PrintableStyle,
}
impl App {
pub fn new(
capture_pattern: Option<Regex>,
rg_cmdline: String,
rg_messages: Vec<RgMessage>,
) -> App {
let mut list = vec![];
let mut maybe_stats = None;
for (i, rg_message) in rg_messages.into_iter().enumerate() {
match rg_message {
RgMessage::Summary { stats, .. } => {
maybe_stats = Some(stats);
break;
}
other => list.push(Item::new(i, other)),
}
}
App {
state: AppState::Running,
capture_pattern,
rg_cmdline,
stats: maybe_stats.expect("failed to find RgMessage::Summary from rg!"),
list_state: AppListState::new(),
list,
ui_state: AppUiState::SelectMatches,
help_text_state: HelpTextState::new(HELP_TEXT),
printable_style: PrintableStyle::default(),
}
}
pub fn get_replacement_criteria(self) -> Result<ReplacementCriteria> {
match self.ui_state {
AppUiState::InputReplacement(user_replacement, _)
| AppUiState::ConfirmReplacement(user_replacement, _) => Ok(ReplacementCriteria::new(
self.capture_pattern,
user_replacement,
self.list,
)),
other => bail!(
"unexpected app ui state when calling App::get_replacement_criteria: {:?}",
other
),
}
}
}