rustyrails_cli/
template.rs

1use std::str::FromStr;
2
3use dialoguer::{theme::ColorfulTheme, Select};
4use serde_derive::{Deserialize, Serialize};
5use serde_variant::to_variant_name;
6use strum::{EnumIter, EnumString, IntoEnumIterator};
7
8#[derive(clap::ValueEnum, Clone, Serialize, Deserialize, Debug, EnumIter, EnumString)]
9pub enum Starter {
10    #[serde(rename = "Saas")]
11    #[strum(serialize = "Saas")]
12    Saas,
13    #[serde(rename = "Stateless (not db)")]
14    #[strum(serialize = "Stateless (not db)")]
15    Stateless,
16}
17
18impl std::fmt::Display for Starter {
19    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20        to_variant_name(self).expect("only enum supported").fmt(f)
21    }
22}
23
24impl Starter {
25    #[must_use]
26    pub fn to_list() -> Vec<String> {
27        Self::iter().map(|provider| provider.to_string()).collect()
28    }
29
30    /// Show interactive starter selection
31    ///
32    /// # Errors
33    /// When could not show the prompt or could not convert selection the
34    /// [`Starter`]
35    pub fn prompt_selection() -> eyre::Result<Self> {
36        let selections = Self::to_list();
37        let selection = Select::with_theme(&ColorfulTheme::default())
38            .with_prompt("Choose starter template")
39            .default(0)
40            .items(&selections[..])
41            .interact()?;
42
43        println!("{}", &selections[selection]);
44        Ok(Self::from_str(&selections[selection])?)
45    }
46
47    #[must_use]
48    pub fn git_url(&self) -> String {
49        match self {
50            Self::Saas => "https://github.com/rustyrails-rs/saas-starter-template".to_string(),
51            Self::Stateless => {
52                "https://github.com/rustyrails-rs/stateless-starter-template".to_string()
53            }
54        }
55    }
56}