Skip to main content

workflow_utils/
action.rs

1use crate::imports::*;
2use workflow_core::enums::Describe;
3
4/// An enumerable command that can be presented to the user as an interactive
5/// CLI selection and then executed against a shared `Context`.
6pub trait Action<Context>: Describe + Clone + Copy + Eq {
7    /// Error type returned when running the action fails.
8    type Error;
9
10    /// Prompts the user to pick a single action using the type's default caption.
11    fn select() -> std::result::Result<Self, std::io::Error> {
12        Self::select_with_prompt(Self::caption())
13    }
14
15    /// Prompts the user to pick a single action using the supplied prompt text.
16    fn select_with_prompt<S>(prompt: S) -> std::result::Result<Self, std::io::Error>
17    where
18        S: Display,
19    {
20        let mut selector = cliclack::select(prompt.to_string());
21        for action in Self::iter() {
22            selector = selector.item(*action, action.describe(), action.rustdoc());
23        }
24
25        selector.interact()
26    }
27
28    /// Prompts the user to pick multiple actions using the default caption,
29    /// pre-selecting `values`.
30    fn multiselect<S>(values: Vec<Self>) -> std::result::Result<Vec<Self>, std::io::Error> {
31        Self::multiselect_with_prompt(Self::caption(), values)
32    }
33
34    /// Prompts the user to pick multiple actions using the supplied prompt text,
35    /// pre-selecting `values`.
36    fn multiselect_with_prompt<S>(
37        prompt: S,
38        values: Vec<Self>,
39    ) -> std::result::Result<Vec<Self>, std::io::Error>
40    where
41        S: Display,
42    {
43        let mut selector = cliclack::multiselect(prompt.to_string()).initial_values(values);
44        for option in Self::into_iter() {
45            selector = selector.item(option, option.describe(), option.rustdoc());
46        }
47
48        selector.interact()
49    }
50
51    /// Executes the selected action, mutating the shared `Context` as needed.
52    fn run(&self, _ctx: &mut Context) -> std::result::Result<(), Self::Error>;
53}