1use anyhow::Result;
2use inquire::InquireError;
3
4mod spinner;
5mod theme;
6
7pub use spinner::Spinner;
8pub use theme::Style;
9
10const fn is_prompt_cancelled(err: &InquireError) -> bool {
12 matches!(
13 err,
14 InquireError::OperationCanceled | InquireError::OperationInterrupted
15 )
16}
17
18pub fn handle_prompt_cancellation<F>(f: F) -> Result<()>
23where
24 F: FnOnce() -> Result<()>,
25{
26 match f() {
27 Ok(()) => Ok(()),
28 Err(e)
29 if e.downcast_ref::<InquireError>()
30 .is_some_and(is_prompt_cancelled) =>
31 {
32 println!();
33 Ok(())
34 }
35 Err(e) => Err(e),
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 #[test]
44 fn test_handle_prompt_cancellation_ok() {
45 let result = handle_prompt_cancellation(|| Ok(()));
46 assert!(result.is_ok());
47 }
48
49 #[test]
50 fn test_handle_prompt_cancellation_operation_canceled() {
51 let result = handle_prompt_cancellation(|| Err(InquireError::OperationCanceled.into()));
52 assert!(result.is_ok());
53 }
54
55 #[test]
56 fn test_handle_prompt_cancellation_operation_interrupted() {
57 let result = handle_prompt_cancellation(|| Err(InquireError::OperationInterrupted.into()));
58 assert!(result.is_ok());
59 }
60
61 #[test]
62 fn test_handle_prompt_cancellation_other_error() {
63 let result = handle_prompt_cancellation(|| Err(anyhow::anyhow!("Some other error")));
64 let Err(err) = result else {
65 panic!("expected an error");
66 };
67 assert!(err.to_string().contains("Some other error"));
68 }
69
70 #[test]
71 fn test_is_prompt_cancelled_operation_canceled() {
72 assert!(is_prompt_cancelled(&InquireError::OperationCanceled));
73 }
74
75 #[test]
76 fn test_is_prompt_cancelled_operation_interrupted() {
77 assert!(is_prompt_cancelled(&InquireError::OperationInterrupted));
78 }
79
80 #[test]
81 fn test_is_prompt_cancelled_other_error() {
82 let err = InquireError::Custom("test".into());
83 assert!(!is_prompt_cancelled(&err));
84 }
85}