barley_interface/
lib.rs

1#![deny(missing_docs)]
2
3//! `barley-interface`
4//! 
5//! This crate provides a simple CLI interface for the `barley`
6//! workflow engine. It should be used instead of the [`Context`]
7//! struct from the `barley-runtime` crate, since it provides
8//! debug callbacks for progress tracking.
9
10use barley_runtime::prelude::*;
11use std::sync::Arc;
12use tokio::sync::RwLock;
13use colored::*;
14
15/// A simple CLI interface for the `barley` workflow engine.
16/// 
17/// This interface is not yet complete, but should be used instead
18/// of the [`Context`] struct from the `barley-runtime` crate,
19/// since it will require no extra modifications when stable.
20pub struct Interface {
21    ctx: Arc<RwLock<Context>>
22}
23
24impl Interface {
25    /// Create a new `Interface`.
26    pub fn new() -> Self {
27        let callbacks = ContextCallbacks {
28            on_action_started: Some(Self::on_action_started),
29            on_action_finished: Some(Self::on_action_finished),
30            on_action_failed: Some(Self::on_action_failed)
31        };
32
33        Self {
34            ctx: Context::new(callbacks)
35        }
36    }
37
38    /// Add an action to the context.
39    pub async fn add_action<A: Action + 'static>(&self, action: A) -> ActionObject {
40        self.ctx.clone().add_action(action).await
41    }
42
43    /// Update an ActionObject.
44    pub async fn update_action(&self, action: ActionObject) {
45        self.ctx.clone().update_action(action).await
46    }
47
48    /// Run the context.
49    pub async fn run(&self) -> Result<()> {
50        self.ctx.clone().run().await
51    }
52
53    /// Gets the output of the action.
54    /// 
55    /// This method will return `None` if the action
56    /// has not been run yet. See [`Context::get_output`]
57    /// for more information.
58    /// 
59    /// [`Context::get_output`]: https://docs.rs/barley-runtime/latest/barley_runtime/struct.Context.html#method.get_output
60    pub async fn get_output(&self, action: ActionObject) -> Option<ActionOutput> {
61        self.ctx.clone().get_output(action).await
62    }
63
64    pub(crate) fn on_action_started(action: ActionObject) {
65        let display_name = action.display_name();
66
67        if !display_name.is_empty() {
68            println!("{} {}", "[STARTED]".yellow(), display_name);
69        }
70    }
71
72    pub(crate) fn on_action_finished(action: ActionObject) {
73        let display_name = action.display_name();
74
75        if !display_name.is_empty() {
76            println!("{} {}", "[FINISHED]".green(), display_name);
77        }
78    }
79
80    pub(crate) fn on_action_failed(action: ActionObject, _err: &Error) {
81        let display_name = action.display_name();
82
83        if !display_name.is_empty() {
84            println!("{} {}", "[FAILED]".red(), display_name);
85        }
86    }
87}
88
89impl Default for Interface {
90    fn default() -> Self {
91        Self::new()
92    }
93}