use crate::Codex;
use crate::command::CodexCommand;
use crate::error::Result;
use crate::exec::{self, CommandOutput};
#[derive(Debug, Clone)]
pub struct DoctorCommand {
json: bool,
summary: bool,
all: bool,
no_color: bool,
ascii: bool,
config_overrides: Vec<String>,
enabled_features: Vec<String>,
disabled_features: Vec<String>,
retry_policy: Option<crate::retry::RetryPolicy>,
}
impl DoctorCommand {
#[must_use]
pub fn new() -> Self {
Self {
json: false,
summary: false,
all: false,
no_color: false,
ascii: false,
config_overrides: Vec::new(),
enabled_features: Vec::new(),
disabled_features: Vec::new(),
retry_policy: None,
}
}
#[must_use]
pub fn json(mut self) -> Self {
self.json = true;
self
}
#[must_use]
pub fn summary(mut self) -> Self {
self.summary = true;
self
}
#[must_use]
pub fn all(mut self) -> Self {
self.all = true;
self
}
#[must_use]
pub fn no_color(mut self) -> Self {
self.no_color = true;
self
}
#[must_use]
pub fn ascii(mut self) -> Self {
self.ascii = true;
self
}
#[must_use]
pub fn config(mut self, key_value: impl Into<String>) -> Self {
self.config_overrides.push(key_value.into());
self
}
#[must_use]
pub fn enable(mut self, feature: impl Into<String>) -> Self {
self.enabled_features.push(feature.into());
self
}
#[must_use]
pub fn disable(mut self, feature: impl Into<String>) -> Self {
self.disabled_features.push(feature.into());
self
}
#[must_use]
pub fn retry(mut self, policy: crate::retry::RetryPolicy) -> Self {
self.retry_policy = Some(policy);
self
}
}
impl Default for DoctorCommand {
fn default() -> Self {
Self::new()
}
}
impl CodexCommand for DoctorCommand {
type Output = CommandOutput;
fn args(&self) -> Vec<String> {
let mut args = vec!["doctor".to_string()];
for value in &self.config_overrides {
args.push("-c".into());
args.push(value.clone());
}
for value in &self.enabled_features {
args.push("--enable".into());
args.push(value.clone());
}
for value in &self.disabled_features {
args.push("--disable".into());
args.push(value.clone());
}
if self.json {
args.push("--json".into());
}
if self.summary {
args.push("--summary".into());
}
if self.all {
args.push("--all".into());
}
if self.no_color {
args.push("--no-color".into());
}
if self.ascii {
args.push("--ascii".into());
}
args
}
async fn execute(&self, codex: &Codex) -> Result<CommandOutput> {
exec::run_codex_with_retry(codex, self.args(), self.retry_policy.as_ref()).await
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn doctor_args_default() {
let args = DoctorCommand::new().args();
assert_eq!(args, vec!["doctor"]);
}
#[test]
fn doctor_args_flags() {
let args = DoctorCommand::new().json().summary().all().args();
assert_eq!(args, vec!["doctor", "--json", "--summary", "--all"]);
}
#[test]
fn doctor_args_config_and_output() {
let args = DoctorCommand::new()
.config("model=o3")
.no_color()
.ascii()
.args();
assert_eq!(
args,
vec!["doctor", "-c", "model=o3", "--no-color", "--ascii"]
);
}
}