lunar_lib/prompts.rs
1use std::{
2 fmt::{Arguments, Debug},
3 sync::OnceLock,
4};
5
6mod cli_prompter;
7pub use cli_prompter::*;
8
9static PROMPTER: OnceLock<&'static dyn Prompter> = OnceLock::new();
10pub fn set_prompter(prompter: &'static dyn Prompter) -> Result<(), &'static dyn Prompter> {
11 PROMPTER.set(prompter)
12}
13pub fn get_prompter() -> Option<&'static dyn Prompter> {
14 PROMPTER.get().copied()
15}
16
17pub trait Prompter: Sync + Debug {
18 /// Tells the prompter to start an "Okay" prompt
19 ///
20 /// This prompt just requires user input for a confirmation something happend.
21 /// An example usage is "Press any key to continue..."
22 fn okay(&self, msg: Arguments);
23
24 /// Tells the prompter to start a "Yes/No" prompt
25 ///
26 /// This prompt just requires user input for a confirmation if they want to do something.
27 /// An example usage is "Are you sure you want to do this? \[Y/n\]"
28 ///
29 /// This function should return [`None`] if the result couldn't be parsed
30 fn ask(&self, msg: Arguments, default: bool) -> Option<bool>;
31}
32
33/// Requests an "Okay" prompt to the current prompter lazily using format args
34///
35/// If no prompter is set, the args will not be parsed
36#[macro_export]
37macro_rules! okay {
38 ($($arg:tt)*) => {{
39 if let Some(prompter) = $crate::prompts::get_prompter() {
40 prompter.okay(format_args!($($arg)*));
41 }
42 }};
43}
44
45/// Requests an "Ask" or "Yes/No" prompt to the current prompter lazily using format args
46///
47/// If no prompter is set, the args will not be parsed
48#[macro_export]
49macro_rules! ask {
50 ($default:expr, $($arg:tt)*) => {{
51 if let Some(prompter) = $crate::prompts::get_prompter() {
52 prompter.ask(format_args!($($arg)*), $default)
53 } else {
54 None
55 }
56 }};
57}