use crate::config::ApprovalMode;
use super::protocol::{SessionMode, SessionModeId, SessionModeState};
const MODES: [ApprovalMode; 3] = [
ApprovalMode::Protective,
ApprovalMode::Normal,
ApprovalMode::Off,
];
pub(super) fn mode_id(mode: ApprovalMode) -> SessionModeId {
SessionModeId::new(mode.as_str())
}
fn describe(mode: ApprovalMode) -> (&'static str, &'static str) {
match mode {
ApprovalMode::Protective => (
"Protective",
"Ask before any state-changing action: writing or deleting files, \
git commits/pushes, installing packages, or any non-read-only \
command.",
),
ApprovalMode::Normal => (
"Normal",
"Ask only before destructive, irreversible, or outward-facing \
actions (deletes, rm -rf, force-push, publishing). Ordinary edits \
proceed without asking.",
),
ApprovalMode::Off => ("Off", "Never pause for approval; act autonomously."),
}
}
pub(super) fn session_mode_state(current: ApprovalMode) -> SessionModeState {
let available = MODES
.iter()
.map(|&mode| {
let (name, description) = describe(mode);
SessionMode::new(mode_id(mode), name).description(Some(description.to_string()))
})
.collect();
SessionModeState::new(mode_id(current), available)
}
pub(super) fn approval_mode_from_id(id: &str) -> Option<ApprovalMode> {
ApprovalMode::parse(id)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn state_lists_all_modes_with_current_selected() {
let state = session_mode_state(ApprovalMode::Protective);
assert_eq!(state.current_mode_id, mode_id(ApprovalMode::Protective));
let ids: Vec<String> = state
.available_modes
.iter()
.map(|m| m.id.to_string())
.collect();
assert_eq!(ids, vec!["protective", "normal", "off"]);
assert!(
state
.available_modes
.iter()
.all(|m| m.description.is_some())
);
}
#[test]
fn mode_id_roundtrips_through_approval_mode_from_id() {
for mode in MODES {
let id = mode_id(mode);
assert_eq!(approval_mode_from_id(&id.to_string()), Some(mode));
}
}
#[test]
fn approval_mode_from_id_accepts_aliases_and_rejects_junk() {
assert_eq!(
approval_mode_from_id("paranoid"),
Some(ApprovalMode::Protective)
);
assert_eq!(approval_mode_from_id("yolo"), Some(ApprovalMode::Off));
assert_eq!(approval_mode_from_id("whenever"), None);
}
}