relay/
utils.rs

1use std::fmt::Display;
2use std::str::FromStr;
3
4use anyhow::Result;
5use dialoguer::Input;
6use dialoguer::theme::{ColorfulTheme, Theme};
7use once_cell::sync::Lazy;
8
9static THEME: Lazy<ColorfulTheme> = Lazy::new(ColorfulTheme::default);
10
11/// Returns the theme to use.
12pub fn get_theme() -> &'static dyn Theme {
13    &*THEME
14}
15
16/// Prompts for a value that has a default.
17pub fn prompt_value<V: FromStr + Display>(name: &str, v: &mut V) -> Result<()>
18where
19    <V as FromStr>::Err: Display,
20{
21    loop {
22        let s = Input::with_theme(get_theme())
23            .with_prompt(name)
24            .default(v.to_string())
25            .interact()?;
26        match s.parse() {
27            Ok(value) => {
28                *v = value;
29                return Ok(());
30            }
31            Err(err) => {
32                println!("  invalid input: {err}");
33                continue;
34            }
35        }
36    }
37}
38
39/// Prompts for a value without a default.
40pub fn prompt_value_no_default<V: FromStr + Display>(name: &str) -> Result<V>
41where
42    <V as FromStr>::Err: Display,
43{
44    loop {
45        let s: String = Input::with_theme(get_theme())
46            .with_prompt(name)
47            .interact()?;
48        match s.parse() {
49            Ok(value) => {
50                return Ok(value);
51            }
52            Err(err) => {
53                println!("  invalid input: {err}");
54                continue;
55            }
56        }
57    }
58}