use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum PermissionMode {
ReadOnly,
Plan,
Default,
Edit,
Auto,
Bypass,
}
impl PermissionMode {
pub const ALL: [PermissionMode; 6] = [
PermissionMode::ReadOnly,
PermissionMode::Plan,
PermissionMode::Default,
PermissionMode::Edit,
PermissionMode::Auto,
PermissionMode::Bypass,
];
pub fn as_str(self) -> &'static str {
match self {
PermissionMode::ReadOnly => "read-only",
PermissionMode::Plan => "plan",
PermissionMode::Default => "default",
PermissionMode::Edit => "edit",
PermissionMode::Auto => "auto",
PermissionMode::Bypass => "bypass",
}
}
pub fn parse(s: &str) -> Result<Self, String> {
PermissionMode::ALL
.into_iter()
.find(|m| m.as_str() == s)
.ok_or_else(|| format!("must be one of {}, got `{s}`", Self::valid_list()))
}
pub fn valid_list() -> String {
PermissionMode::ALL
.iter()
.map(|m| m.as_str())
.collect::<Vec<_>>()
.join(", ")
}
pub fn from_bypass(bypass: bool) -> Self {
if bypass {
PermissionMode::Bypass
} else {
PermissionMode::Default
}
}
pub fn is_bypass(self) -> bool {
matches!(self, PermissionMode::Bypass)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum ModeHeadless {
Clean,
Hangs,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_round_trips_every_mode() {
for m in PermissionMode::ALL {
assert_eq!(PermissionMode::parse(m.as_str()).unwrap(), m);
}
}
#[test]
fn parse_rejects_unknown_with_a_listing() {
let err = PermissionMode::parse("yolo").unwrap_err();
assert!(err.contains("yolo"), "{err}");
assert!(err.contains("bypass"), "lists valid values: {err}");
}
#[test]
fn bypass_bridge_maps_both_ways() {
assert_eq!(PermissionMode::from_bypass(true), PermissionMode::Bypass);
assert_eq!(PermissionMode::from_bypass(false), PermissionMode::Default);
assert!(PermissionMode::Bypass.is_bypass());
assert!(!PermissionMode::Default.is_bypass());
}
#[test]
fn serializes_as_kebab_tokens() {
let json = serde_json::to_string(&PermissionMode::Bypass).unwrap();
assert_eq!(json, "\"bypass\"");
let parsed: PermissionMode = serde_json::from_str("\"plan\"").unwrap();
assert_eq!(parsed, PermissionMode::Plan);
}
}