1use sparcli::event::{KeyCode, KeyPress};
8use sparcli::shortcut::{self, Shortcut};
9use sparcli::validate::{alnum, non_empty};
10use sparcli::{
11 Alert, Confirm, DatePicker, NumberInput, Outcome, PasswordInput,
12 Renderable, Rendered, Select, TextInput, Textarea,
13};
14
15#[cfg(feature = "fuzzy")]
16use sparcli::FuzzySelect;
17
18macro_rules! get {
20 ($prompt:expr) => {
21 match $prompt {
22 Outcome::Submitted(value) => value,
23 _ => return cancelled(),
24 }
25 };
26}
27
28fn main() -> sparcli::Result<()> {
29 footer_hint()?;
30
31 let name = get!(
32 TextInput::new("Your name?")
33 .placeholder("e.g. Alice")
34 .validate(non_empty())
35 .run()?
36 );
37
38 let _username = get!(
39 TextInput::new("Username?")
40 .char_filter(alnum())
41 .max_chars(16)
42 .suggestions(["alice", "albert", "bob", "carol"])
43 .history(["alice", "bob"])
44 .run()?
45 );
46
47 let _password = get!(PasswordInput::new("Password?").mask("•").run()?);
48
49 let age = get!(
50 NumberInput::new("Age? (try `= 20 + 2`)")
51 .range(0.0, 130.0)
52 .calculator()
53 .run()?
54 );
55
56 let _bio = get!(Textarea::new("Short bio (Ctrl-D to submit):").run()?);
57
58 let color = get!(
59 Select::new("Favorite color?")
60 .options(["red", "green", "blue"])
61 .run()?
62 );
63
64 let toppings = get!(
65 Select::new("Pick toppings (Space to toggle):")
66 .options(["cheese", "mushroom", "olive", "onion"])
67 .multi()
68 .run_multi()?
69 );
70
71 let _fruit = get!(pick_fruit()?);
72
73 let date = get!(DatePicker::new("Pick a date:").run()?);
74
75 let confirmed = matches!(
76 Confirm::new("Save everything?")
77 .default_yes()
78 .labels("Save", "Discard")
79 .run()?,
80 Outcome::Submitted(true)
81 );
82
83 if confirmed {
84 Alert::success(format!(
85 "Saved {name}, age {age:.0}, color #{color}, {} toppings, \
86 date {}-{:02}-{:02}.",
87 toppings.len(),
88 date.year,
89 date.month,
90 date.day,
91 ))
92 .print()?;
93 } else {
94 cancelled()?;
95 }
96 Ok(())
97}
98
99#[cfg(feature = "fuzzy")]
101fn pick_fruit() -> sparcli::Result<Outcome<usize>> {
102 FuzzySelect::new("Find a fruit:")
103 .options(["apple", "apricot", "banana", "cherry", "grape"])
104 .run()
105}
106
107#[cfg(not(feature = "fuzzy"))]
109fn pick_fruit() -> sparcli::Result<Outcome<usize>> {
110 Ok(Outcome::Submitted(0))
111}
112
113fn footer_hint() -> sparcli::Result<()> {
115 let shortcuts = [
116 Shortcut::new(KeyPress::new(KeyCode::Enter), 1, "submit"),
117 Shortcut::new(KeyPress::new(KeyCode::Esc), 2, "cancel"),
118 ];
119 Rendered::new(vec![shortcut::hint_line(&shortcuts)]).print()
120}
121
122fn cancelled() -> sparcli::Result<()> {
124 Alert::warning("Cancelled.").print()
125}