use std::path::PathBuf;
use anyhow::{Context as _, Result};
use super::{Cli, Command};
use crate::active_session;
use crate::client::{Client, Response};
use crate::paths::Paths;
use crate::spawn;
#[must_use]
pub fn resolve_paths(home_override: Option<&PathBuf>) -> Paths {
match home_override {
Some(p) => Paths::at(p.clone()),
None => Paths::home(),
}
}
pub fn resolve_session(cli: &Cli, paths: &Paths) -> Result<Option<String>> {
if let Some(s) = &cli.session {
return Ok(Some(s.clone()));
}
active_session::read(paths.active_session())
}
pub fn connect(cli: &Cli, paths: &Paths) -> Result<Client> {
let socket = cli.socket.clone().unwrap_or_else(|| paths.socket());
if !vs_daemon::transport::is_listening(&socket) && !cli.no_spawn {
let mut extra: Vec<String> = Vec::new();
if let Some(home) = cli.home.as_ref() {
extra.push(format!("--home={}", home.display()));
}
let extra_refs: Vec<&str> = extra.iter().map(String::as_str).collect();
spawn::spawn_daemon(&extra_refs)?;
spawn::wait_for_socket(&socket, std::time::Duration::from_secs(2))?;
}
Client::connect(&socket)
}
pub fn run(cli: &Cli) -> Result<Response> {
let paths = resolve_paths(cli.home.as_ref());
let session_id = resolve_session(cli, &paths)?;
let mut client = connect(cli, &paths)?;
let req = cli.command.to_request(session_id.as_deref())?;
let resp = client.call(&req).context("daemon call")?;
match (&cli.command, &resp.envelope) {
(Command::SessionOpen { .. }, vs_protocol::Envelope::Success(_)) => {
if let Some(line) = resp.body.first() {
active_session::write(paths.active_session(), line.trim())?;
}
}
(Command::SessionClose, vs_protocol::Envelope::Success(_)) => {
active_session::clear(paths.active_session())?;
}
_ => {}
}
Ok(resp)
}