use std::sync::Arc;
use crate::command::{CommandRequest, CommandResult, ProcessStatus};
use crate::control::ControlSender;
use crate::internal::executor::{DispatchFuture, DispatchSpan, Executor, ShutdownFuture};
pub(crate) struct ControlModeExecutor {
sender: Arc<ControlSender>,
}
impl ControlModeExecutor {
pub(crate) fn new(sender: ControlSender) -> Self {
Self {
sender: Arc::new(sender),
}
}
}
impl Executor for ControlModeExecutor {
fn execute(&self, request: CommandRequest) -> DispatchFuture {
let sender = Arc::clone(&self.sender);
let span = DispatchSpan::new(&request, "control");
let request_id = request.request_id();
let summary = request.summary().clone();
let sensitive_input = summary.sensitive_argument_count() > 0;
let commands = request.command_count();
let line = request.into_control_line();
span.run(async move {
let Some(line) = line else {
return Err(crate::Error::control_mode_unrepresentable());
};
let block = sender.send_line(line, sensitive_input, commands).await?;
let bytes = |lines: &[crate::TmuxText]| {
let mut bytes = Vec::new();
for line in lines {
bytes.extend_from_slice(line.as_bytes());
bytes.push(b'\n');
}
bytes
};
let (stdout, stderr) = block.split_by_outcome();
Ok(CommandResult::new(
request_id,
summary,
ProcessStatus::from_block_outcome(block.succeeded()),
bytes(stdout),
bytes(stderr),
))
})
}
fn shutdown(&self) -> ShutdownFuture {
ShutdownFuture::new(async { Ok(()) })
}
fn renders_control_line(&self) -> bool {
true
}
}