use super::jsonc::Root;
use crate::{
config::{FileContents, Override},
error::{ErrorKind, Result},
};
use jsonc_parser::cst::CstInputValue;
#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "config_file", derive(serde::Deserialize, serde::Serialize))]
pub enum Permission {
Deny,
Confirm,
Allow,
}
impl From<Permission> for CstInputValue {
fn from(value: Permission) -> Self {
let s = match value {
Permission::Deny => "deny",
Permission::Confirm => "confirm",
Permission::Allow => "allow",
};
Self::String(s.into())
}
}
#[derive(Debug)]
#[cfg_attr(feature = "config_file", derive(serde::Deserialize, serde::Serialize))]
#[non_exhaustive]
pub struct ZedSettings {
pub tool_permission: Option<Permission>,
}
impl Default for ZedSettings {
fn default() -> Self {
Self::new()
}
}
impl ZedSettings {
pub const fn new() -> Self {
Self {
tool_permission: None,
}
}
pub const fn tool_permission(&mut self, permission: Permission) -> &mut Self {
self.tool_permission = Some(permission);
self
}
#[must_use]
pub const fn take(&mut self) -> Self {
Self {
tool_permission: self.tool_permission.take(),
}
}
}
impl Override for ZedSettings {
fn apply(&self, contents: FileContents) -> Result<()> {
let Some(tool_permission) = self.tool_permission else {
return Ok(());
};
let mut root = Root::read_from(
"zed",
contents,
ErrorKind::InvalidOpencodeConfigSyntax,
ErrorKind::InvalidOpencodeConfigSchema,
)?;
let root_object = root.get_object()?;
let agent_object = root_object.get_object_value("agent")?;
let tool_permissions = agent_object.get_object_value("tool_permissions")?;
tool_permissions.insert_value("default", tool_permission);
root.write()?;
Ok(())
}
}