use crate::relay_lock;
#[derive(Debug)]
pub enum StopResult {
Stopped { pid: u32 },
StaleCleaned,
}
#[derive(Debug)]
pub struct RelayStatusInfo {
pub pid: u32,
pub port: u16,
pub started_at: i64,
}
pub fn stop_relay() -> Result<StopResult, String> {
match relay_lock::check_lock() {
relay_lock::LockStatus::Held(info) => {
let pid = info.pid;
relay_lock::stop_relay();
Ok(StopResult::Stopped { pid })
}
relay_lock::LockStatus::Stale(_) => {
relay_lock::remove_lock();
Ok(StopResult::StaleCleaned)
}
relay_lock::LockStatus::Free => Err("relay is not running.".to_string()),
}
}
pub fn relay_status() -> Result<RelayStatusInfo, String> {
match relay_lock::check_lock() {
relay_lock::LockStatus::Held(info) => Ok(RelayStatusInfo {
pid: info.pid,
port: info.port,
started_at: info.started_at,
}),
relay_lock::LockStatus::Stale(_) => {
relay_lock::remove_lock();
Err("relay is not running (stale lock cleaned up).".to_string())
}
relay_lock::LockStatus::Free => Err("relay is not running.".to_string()),
}
}
#[cfg(test)]
#[allow(non_snake_case)]
mod tests {
use super::*;
#[cfg(unix)]
#[test]
fn lifecycle__all_paths() {
relay_lock::remove_lock();
let result = stop_relay();
assert!(result.is_err());
assert!(result.unwrap_err().contains("not running"));
let result = relay_status();
assert!(result.is_err());
assert!(result.unwrap_err().contains("not running"));
relay_lock::write_lock(7777, "/tmp/test-relay.toml").unwrap();
let result = relay_status();
assert!(result.is_ok());
let info = result.unwrap();
assert_eq!(info.pid, std::process::id());
assert_eq!(info.port, 7777);
assert!(info.started_at > 0);
relay_lock::remove_lock();
}
}