1use std::error::Error;
2use std::net::IpAddr;
3
4use console::Style;
5use dialoguer_ext::{theme::ColorfulTheme, Confirm, Input, Select};
6
7#[derive(Debug)]
8#[allow(dead_code)]
9struct Config {
10 interface: IpAddr,
11 hostname: String,
12 use_acme: bool,
13 private_key: Option<String>,
14 cert: Option<String>,
15}
16
17fn init_config() -> Result<Option<Config>, Box<dyn Error>> {
18 let theme = ColorfulTheme {
19 values_style: Style::new().yellow().dim(),
20 ..ColorfulTheme::default()
21 };
22 println!("Welcome to the setup wizard");
23
24 if !Confirm::with_theme(&theme)
25 .with_prompt("Do you want to continue?")
26 .interact()?
27 {
28 return Ok(None);
29 }
30
31 let interface = Input::with_theme(&theme)
32 .with_prompt("Interface")
33 .default("127.0.0.1".parse().unwrap())
34 .interact()?;
35
36 let hostname = Input::with_theme(&theme)
37 .with_prompt("Hostname")
38 .interact()?;
39
40 let tls = Select::with_theme(&theme)
41 .with_prompt("Configure TLS")
42 .default(0)
43 .item("automatic with ACME")
44 .item("manual")
45 .item("no")
46 .interact()?;
47
48 let (private_key, cert, use_acme) = match tls {
49 0 => (Some("acme.pkey".into()), Some("acme.cert".into()), true),
50 1 => (
51 Some(
52 Input::with_theme(&theme)
53 .with_prompt(" Path to private key")
54 .interact()?,
55 ),
56 Some(
57 Input::with_theme(&theme)
58 .with_prompt(" Path to certificate")
59 .interact()?,
60 ),
61 false,
62 ),
63 _ => (None, None, false),
64 };
65
66 Ok(Some(Config {
67 hostname,
68 interface,
69 private_key,
70 cert,
71 use_acme,
72 }))
73}
74
75fn main() {
76 match init_config() {
77 Ok(None) => println!("Aborted."),
78 Ok(Some(config)) => println!("{:#?}", config),
79 Err(err) => println!("error: {}", err),
80 }
81}