#![cfg_attr(test, allow(clippy::expect_used, clippy::unwrap_used))]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum PermissionMode {
Bypass,
AcceptEdits,
Prompt,
}
impl Default for PermissionMode {
fn default() -> Self {
PermissionMode::Prompt
}
}
impl std::str::FromStr for PermissionMode {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"bypass" => Ok(Self::Bypass),
"accept-edits" => Ok(Self::AcceptEdits),
"prompt" => Ok(Self::Prompt),
other => Err(format!(
"unknown mode: {other}; expected bypass | accept-edits | prompt"
)),
}
}
}
impl std::fmt::Display for PermissionMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
Self::Bypass => "bypass",
Self::AcceptEdits => "accept-edits",
Self::Prompt => "prompt",
};
f.write_str(s)
}
}
pub fn next_mode(current: PermissionMode) -> PermissionMode {
match current {
PermissionMode::Prompt => PermissionMode::AcceptEdits,
PermissionMode::AcceptEdits => PermissionMode::Bypass,
PermissionMode::Bypass => PermissionMode::Prompt,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_is_prompt() {
assert_eq!(PermissionMode::default(), PermissionMode::Prompt);
}
#[test]
fn next_mode_cycles_three_modes_in_order() {
let mut m = PermissionMode::Prompt;
m = next_mode(m);
assert_eq!(m, PermissionMode::AcceptEdits);
m = next_mode(m);
assert_eq!(m, PermissionMode::Bypass);
m = next_mode(m);
assert_eq!(m, PermissionMode::Prompt);
}
#[test]
fn from_str_round_trips_all_three() {
for m in [
PermissionMode::Bypass,
PermissionMode::AcceptEdits,
PermissionMode::Prompt,
] {
let s = m.to_string();
let back: PermissionMode = s.parse().expect("parse");
assert_eq!(back, m, "round-trip failed for {s}");
}
}
#[test]
fn from_str_rejects_unknown() {
let result: Result<PermissionMode, _> = "wibble".parse();
assert!(result.is_err());
}
#[test]
fn serde_round_trips_via_json() {
let m = PermissionMode::AcceptEdits;
let json = serde_json::to_string(&m).expect("serialize");
assert_eq!(json, r#""accept-edits""#);
let back: PermissionMode = serde_json::from_str(&json).expect("deserialize");
assert_eq!(back, m);
}
}