tartarus-api 0.1.1

Structured API for sandboxing system (currently utilizing `bubblewrap`)
Documentation
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(())
    }
}