use crate::{
config::{FileContents, Override, overrides::jsonc::Root},
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,
Ask,
Allow,
}
impl From<Permission> for CstInputValue {
fn from(value: Permission) -> Self {
let s = match value {
Permission::Deny => "deny",
Permission::Ask => "ask",
Permission::Allow => "allow",
};
Self::String(s.into())
}
}
#[derive(Debug)]
#[cfg_attr(feature = "config_file", derive(serde::Deserialize, serde::Serialize))]
#[non_exhaustive]
pub struct OpenCodeSettings {
pub external_directories: Option<Permission>,
}
impl Default for OpenCodeSettings {
fn default() -> Self {
Self::new()
}
}
impl OpenCodeSettings {
pub const fn new() -> Self {
Self {
external_directories: None,
}
}
pub const fn external_directories(&mut self, external_directories: Permission) -> &mut Self {
self.external_directories = Some(external_directories);
self
}
#[must_use]
pub const fn take(&mut self) -> Self {
Self {
external_directories: self.external_directories.take(),
}
}
}
impl Override for OpenCodeSettings {
fn apply(&self, contents: FileContents) -> Result<()> {
let Some(external_directories) = self.external_directories else {
return Ok(());
};
let mut root = Root::read_from(
"opencode",
contents,
ErrorKind::InvalidOpencodeConfigSyntax,
ErrorKind::InvalidOpencodeConfigSchema,
)?;
let root_object = root.get_object()?;
let permission = root_object.get_object_value("permission")?;
permission.insert_value("external_directory", external_directories);
root.write()?;
Ok(())
}
}