objectiveai-cli 2.0.5

ObjectiveAI command-line interface and embeddable library
use clap::Args;

/// How the JSON body is provided.
#[derive(Args)]
#[group(required = true, multiple = false)]
pub struct BodySource {
    /// Inline JSON body
    #[arg(long)]
    body_inline: Option<String>,
    /// Path to a JSON file
    #[arg(long)]
    body_file: Option<std::path::PathBuf>,
    /// Inline Python code that produces the JSON body
    #[arg(long)]
    body_python_inline: Option<String>,
    /// Path to a Python file that produces the JSON body
    #[arg(long)]
    body_python_file: Option<std::path::PathBuf>,
}

impl BodySource {
    pub fn resolve<T: serde::de::DeserializeOwned>(self) -> Result<T, crate::error::Error> {
        if let Some(inline) = self.body_inline {
            let mut de = serde_json::Deserializer::from_str(&inline);
            return serde_path_to_error::deserialize(&mut de)
                .map_err(crate::error::Error::InlineDeserialize);
        }
        if let Some(path) = self.body_file {
            let contents = std::fs::read_to_string(&path)
                .map_err(|e| crate::error::Error::PythonFileRead(path, e))?;
            let mut de = serde_json::Deserializer::from_str(&contents);
            return serde_path_to_error::deserialize(&mut de)
                .map_err(crate::error::Error::InlineDeserialize);
        }
        if let Some(code) = self.body_python_inline {
            return crate::python::exec_code(&code);
        }
        if let Some(path) = self.body_python_file {
            return crate::python::exec_file(&path);
        }
        unreachable!("clap group ensures one is set")
    }
}

/// How the commit message is provided.
#[derive(Args)]
#[group(required = true, multiple = false)]
pub struct MessageSource {
    /// Inline commit message
    #[arg(long)]
    message_inline: Option<String>,
    /// Path to a file containing the commit message
    #[arg(long)]
    message_file: Option<std::path::PathBuf>,
}

impl MessageSource {
    pub fn resolve(self) -> Result<String, crate::error::Error> {
        if let Some(inline) = self.message_inline {
            return Ok(inline);
        }
        if let Some(path) = self.message_file {
            return std::fs::read_to_string(&path)
                .map_err(|e| crate::error::Error::PythonFileRead(path, e));
        }
        unreachable!("clap group ensures one is set")
    }
}