use sparcli::input::event::{KeyCode, KeyPress};
use sparcli::input::shortcut::{self, Shortcut};
use sparcli::input::validate::{alnum, non_empty};
use sparcli::{
Alert, Confirm, DatePicker, NumberInput, Outcome, PasswordInput,
Renderable, Rendered, Select, TextInput, Textarea,
};
#[cfg(feature = "fuzzy")]
use sparcli::FuzzySelect;
macro_rules! get {
($prompt:expr) => {
match $prompt {
Outcome::Submitted(value) => value,
_ => return cancelled(),
}
};
}
fn main() -> sparcli::Result<()> {
footer_hint()?;
let name = get!(
TextInput::new("Your name?")
.placeholder("e.g. Alice")
.validate(non_empty())
.run()?
);
let _username = get!(
TextInput::new("Username?")
.char_filter(alnum())
.max_chars(16)
.suggestions(["alice", "albert", "bob", "carol"])
.history(["alice", "bob"])
.run()?
);
let _password = get!(PasswordInput::new("Password?").mask("•").run()?);
let age = get!(
NumberInput::new("Age? (try `= 20 + 2`)")
.range(0.0, 130.0)
.calculator()
.run()?
);
let _bio = get!(Textarea::new("Short bio (Ctrl-D to submit):").run()?);
let color = get!(
Select::new("Favorite color?")
.options(["red", "green", "blue"])
.run()?
);
let toppings = get!(
Select::new("Pick toppings (Space to toggle):")
.options(["cheese", "mushroom", "olive", "onion"])
.multi()
.run_multi()?
);
let _fruit = get!(pick_fruit()?);
let date = get!(DatePicker::new("Pick a date:").run()?);
let confirmed = matches!(
Confirm::new("Save everything?")
.default_yes()
.labels("Save", "Discard")
.run()?,
Outcome::Submitted(true)
);
if confirmed {
Alert::success(format!(
"Saved {name}, age {age:.0}, color #{color}, {} toppings, \
date {}-{:02}-{:02}.",
toppings.len(),
date.year,
date.month,
date.day,
))
.print()?;
} else {
cancelled()?;
}
Ok(())
}
#[cfg(feature = "fuzzy")]
fn pick_fruit() -> sparcli::Result<Outcome<usize>> {
FuzzySelect::new("Find a fruit:")
.options(["apple", "apricot", "banana", "cherry", "grape"])
.run()
}
#[cfg(not(feature = "fuzzy"))]
fn pick_fruit() -> sparcli::Result<Outcome<usize>> {
Ok(Outcome::Submitted(0))
}
fn footer_hint() -> sparcli::Result<()> {
let shortcuts = [
Shortcut::new(KeyPress::new(KeyCode::Enter), 1, "submit"),
Shortcut::new(KeyPress::new(KeyCode::Esc), 2, "cancel"),
];
Rendered::new(vec![shortcut::hint_line(&shortcuts)]).print()
}
fn cancelled() -> sparcli::Result<()> {
Alert::warning("Cancelled.").print()
}