use std::path::PathBuf;
use getset::Getters;
use typed_builder::TypedBuilder;
use crate::domain::{
process::{ActivityState, ProcessKind, ProcessState, RestartPolicy, StopPolicy},
value::{CommandLine, Description, PaneId, ProcessName},
};
#[derive(Clone, Getters, TypedBuilder)]
#[getset(get = "pub")]
pub struct Process {
id: PaneId,
name: ProcessName,
kind: ProcessKind,
#[builder(default)]
command: Option<CommandLine>,
#[builder(default)]
working_dir: Option<PathBuf>,
#[builder(default)]
description: Option<Description>,
#[builder(default)]
state: ProcessState,
#[builder(default)]
restart: RestartPolicy,
#[builder(default)]
stop: Option<StopPolicy>,
#[builder(default = true)]
autostart: bool,
#[builder(default)]
activity: ActivityState,
}
impl Process {
pub fn set_state(&mut self, state: ProcessState) {
self.state = state;
}
pub fn set_autostart(&mut self, autostart: bool) {
self.autostart = autostart;
}
pub fn set_activity(&mut self, activity: ActivityState) {
self.activity = activity;
}
pub fn effective_stop_policy(&self) -> Option<StopPolicy> {
if self.kind == ProcessKind::Command {
Some(self.stop.clone().unwrap_or_default())
} else {
None
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn builds_with_defaults_for_optional_fields() {
let process = Process::builder()
.id(PaneId::new(1))
.name(ProcessName::try_new("Claude Code").unwrap())
.kind(ProcessKind::Agent)
.command(Some(CommandLine::try_new("claude").unwrap()))
.build();
assert_eq!(*process.kind(), ProcessKind::Agent);
assert_eq!(*process.state(), ProcessState::Pending);
assert!(process.working_dir().is_none());
assert!(process.description().is_none());
}
#[test]
fn command_defaults_to_none() {
let process = Process::builder()
.id(PaneId::new(1))
.name(ProcessName::try_new("shell").unwrap())
.kind(ProcessKind::Terminal)
.build();
assert!(process.command().is_none());
}
}