proplate_core/template/
inquirer.rs

1use std::process::exit;
2
3use inquire::{error::InquireResult, Select, Text};
4use proplate_tui::logger::AsError;
5
6use super::config::{Arg, ArgType};
7
8use proplate_errors::{CliErrorKind, ProplateError, ProplateErrorKind};
9
10/// For mapping input attribute internally
11pub struct InputAttr {
12  /// default value
13  pub default: Option<String>,
14  pub name: String,
15}
16
17pub enum Input<'a> {
18  Text(Text<'a>, InputAttr),
19  Select(Select<'a, String>, InputAttr),
20}
21
22impl<'a> Input<'a> {
23  fn handle_prompt(result: InquireResult<String>) -> String {
24    match result {
25      Ok(t) => t,
26      Err(e) => {
27        // is it really necessary to handle the error here ? if no, return Result<String> then
28        // handle it there
29        eprintln!(
30          "{}",
31          ProplateError::create(ProplateErrorKind::Cli(CliErrorKind::Prompt))
32            .with_cause(&e.to_string())
33            .print_err()
34        );
35        exit(1);
36      }
37    }
38  }
39
40  pub fn prompt(&self) -> String {
41    match self {
42      Input::Text(p, attr) => {
43        let p = p.clone();
44        Self::handle_prompt(
45          p.with_initial_value(attr.default.clone().unwrap_or("".to_string()).as_ref())
46            .prompt(),
47        )
48      }
49      Input::Select(p, _) => Self::handle_prompt(p.clone().prompt()),
50    }
51  }
52
53  pub fn get_attr(&self) -> &InputAttr {
54    match self {
55      Input::Select(_, attr) | Input::Text(_, attr) => attr,
56    }
57  }
58}
59
60impl<'a> From<&'a Arg> for Input<'a> {
61  fn from(value: &'a Arg) -> Self {
62    match value.q_type {
63      ArgType::Text => {
64        let attr = InputAttr {
65          default: value.default_value.clone(),
66          name: value.key.clone(),
67        };
68        Input::Text(Text::new(&value.label), attr)
69      }
70      ArgType::Select => {
71        let options = value.options.clone().unwrap_or_default();
72        let attr = InputAttr {
73          default: None,
74          name: value.key.clone(),
75        };
76        Input::Select(Select::new(&value.label, options), attr)
77      }
78    }
79  }
80}