use crate::daemon::{self, ToggleOutcome};
use crate::error::TalkError;
use std::path::PathBuf;
pub struct RecordToggleOpts {
pub file: Option<PathBuf>,
pub monitor: bool,
pub no_sounds: bool,
pub no_boop: bool,
pub no_overlay: bool,
pub viz: Option<crate::config::VizMode>,
pub mono: bool,
pub no_bt_auto_switch: bool,
pub verbose: u8,
}
fn build_daemon_args(opts: &RecordToggleOpts) -> Vec<String> {
let mut args = Vec::new();
if opts.verbose > 0 {
args.push(format!("-{}", "v".repeat(opts.verbose as usize)));
}
args.push("record".to_string());
args.push("--daemon".to_string());
if opts.monitor {
args.push("--monitor".to_string());
}
if opts.no_sounds {
args.push("--no-sounds".to_string());
}
if opts.no_boop {
args.push("--no-boop".to_string());
}
if opts.no_overlay {
args.push("--no-overlay".to_string());
}
if let Some(viz) = opts.viz {
args.push("--viz".to_string());
args.push(viz.to_string());
}
if opts.mono {
args.push("--mono".to_string());
}
if opts.no_bt_auto_switch {
args.push("--no-bt-auto-switch".to_string());
}
if let Some(path) = &opts.file {
args.push(path.to_string_lossy().into_owned());
}
args
}
pub async fn toggle_dispatch(opts: &RecordToggleOpts) -> Result<(), TalkError> {
let slot = daemon::record_slot()?;
let outcome =
daemon::toggle_current_executable(&slot, || async { Ok(build_daemon_args(opts)) }).await?;
match outcome {
ToggleOutcome::Started { pid, log_path } => log::info!(
"recording started (PID {}, logs: {})",
pid,
log_path.display()
),
ToggleOutcome::Signalled { pid } => slot.trace(&format!(
"[DBG] record toggle sent SIGINT to daemon PID {pid}"
)),
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use std::path::PathBuf;
#[test]
fn record_child_args_forward_only_record_options() {
let opts = RecordToggleOpts {
file: Some(PathBuf::from("/tmp/meeting.ogg")),
monitor: true,
no_sounds: true,
no_boop: true,
no_overlay: true,
viz: Some(crate::config::VizMode::Waterfall),
mono: true,
no_bt_auto_switch: true,
verbose: 2,
};
let args = build_daemon_args(&opts);
assert_eq!(
args,
vec![
"-vv",
"record",
"--daemon",
"--monitor",
"--no-sounds",
"--no-boop",
"--no-overlay",
"--viz",
"waterfall",
"--mono",
"--no-bt-auto-switch",
"/tmp/meeting.ogg",
]
);
assert_eq!(args.iter().filter(|arg| *arg == "--daemon").count(), 1);
assert!(!args.iter().any(|arg| arg == "--toggle"));
assert!(!args.iter().any(|arg| arg == "--ui"));
}
#[test]
fn record_child_args_keep_optional_path_absent() {
let opts = RecordToggleOpts {
file: None,
monitor: false,
no_sounds: false,
no_boop: false,
no_overlay: false,
viz: None,
mono: false,
no_bt_auto_switch: false,
verbose: 0,
};
assert_eq!(build_daemon_args(&opts), vec!["record", "--daemon"]);
}
}