opendev_runtime/ask_user_channel.rs
1//! Ask-user channel types shared between tools and TUI.
2//!
3//! `AskUserRequest` lives here so that both `opendev-tools-impl`
4//! (which blocks inside `AskUserTool::execute()`) and `opendev-tui`
5//! (which renders the ask-user panel) can reference it without a
6//! circular dependency.
7
8use tokio::sync::{mpsc, oneshot};
9
10/// A request sent from `AskUserTool` to the TUI for user input.
11///
12/// The tool creates a oneshot channel, sends this struct through an mpsc
13/// channel, and then awaits the oneshot receiver. The TUI displays the
14/// question, collects the user's answer, and sends it back via `response_tx`.
15#[derive(Debug)]
16pub struct AskUserRequest {
17 /// The question to display.
18 pub question: String,
19 /// Optional list of choices.
20 pub options: Vec<String>,
21 /// Default answer if the user cancels.
22 pub default: Option<String>,
23 /// Oneshot sender the TUI uses to return the user's answer.
24 pub response_tx: oneshot::Sender<String>,
25}
26
27/// Convenience type alias for the sender half that `AskUserTool` holds.
28pub type AskUserSender = mpsc::UnboundedSender<AskUserRequest>;
29
30/// Convenience type alias for the receiver half that the TUI polls.
31pub type AskUserReceiver = mpsc::UnboundedReceiver<AskUserRequest>;
32
33/// Create a paired (sender, receiver) for ask-user communication.
34pub fn ask_user_channel() -> (AskUserSender, AskUserReceiver) {
35 mpsc::unbounded_channel()
36}
37
38#[cfg(test)]
39#[path = "ask_user_channel_tests.rs"]
40mod tests;