use crate::{CliOverridesPatch, ConfigOverride, FlagState};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::{collections::BTreeMap, process::ExitStatus};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(from = "String", into = "String")]
pub enum CodexFeatureStage {
Experimental,
Beta,
Stable,
Deprecated,
Removed,
Unknown(String),
}
impl CodexFeatureStage {
pub(crate) fn parse(raw: &str) -> Self {
let normalized = raw.trim();
match normalized.to_ascii_lowercase().as_str() {
"experimental" => CodexFeatureStage::Experimental,
"beta" => CodexFeatureStage::Beta,
"stable" => CodexFeatureStage::Stable,
"deprecated" => CodexFeatureStage::Deprecated,
"removed" => CodexFeatureStage::Removed,
_ => CodexFeatureStage::Unknown(normalized.to_string()),
}
}
pub fn as_str(&self) -> &str {
match self {
CodexFeatureStage::Experimental => "experimental",
CodexFeatureStage::Beta => "beta",
CodexFeatureStage::Stable => "stable",
CodexFeatureStage::Deprecated => "deprecated",
CodexFeatureStage::Removed => "removed",
CodexFeatureStage::Unknown(label) => label.as_str(),
}
}
}
impl From<String> for CodexFeatureStage {
fn from(value: String) -> Self {
CodexFeatureStage::parse(&value)
}
}
impl From<CodexFeatureStage> for String {
fn from(stage: CodexFeatureStage) -> Self {
String::from(&stage)
}
}
impl From<&CodexFeatureStage> for String {
fn from(stage: &CodexFeatureStage) -> Self {
stage.as_str().to_string()
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct CodexFeature {
pub name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub stage: Option<CodexFeatureStage>,
pub enabled: bool,
#[serde(flatten, default, skip_serializing_if = "BTreeMap::is_empty")]
pub extra: BTreeMap<String, Value>,
}
impl CodexFeature {
pub const fn is_enabled(&self) -> bool {
self.enabled
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum FeaturesListFormat {
Json,
Text,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FeaturesListOutput {
pub status: ExitStatus,
pub stdout: String,
pub stderr: String,
pub features: Vec<CodexFeature>,
pub format: FeaturesListFormat,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FeaturesListRequest {
pub json: bool,
pub overrides: CliOverridesPatch,
}
impl FeaturesListRequest {
pub fn new() -> Self {
Self {
json: false,
overrides: CliOverridesPatch::default(),
}
}
pub fn json(mut self, enable: bool) -> Self {
self.json = enable;
self
}
pub fn with_overrides(mut self, overrides: CliOverridesPatch) -> Self {
self.overrides = overrides;
self
}
pub fn config_override(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.overrides
.config_overrides
.push(ConfigOverride::new(key, value));
self
}
pub fn config_override_raw(mut self, raw: impl Into<String>) -> Self {
self.overrides
.config_overrides
.push(ConfigOverride::from_raw(raw));
self
}
pub fn profile(mut self, profile: impl Into<String>) -> Self {
let profile = profile.into();
self.overrides.profile = (!profile.trim().is_empty()).then_some(profile);
self
}
pub fn oss(mut self, enable: bool) -> Self {
self.overrides.oss = if enable {
FlagState::Enable
} else {
FlagState::Disable
};
self
}
pub fn enable_feature(mut self, name: impl Into<String>) -> Self {
self.overrides.feature_toggles.enable.push(name.into());
self
}
pub fn disable_feature(mut self, name: impl Into<String>) -> Self {
self.overrides.feature_toggles.disable.push(name.into());
self
}
pub fn search(mut self, enable: bool) -> Self {
self.overrides.search = if enable {
FlagState::Enable
} else {
FlagState::Disable
};
self
}
}
impl Default for FeaturesListRequest {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FeaturesCommandRequest {
pub overrides: CliOverridesPatch,
}
impl FeaturesCommandRequest {
pub fn new() -> Self {
Self {
overrides: CliOverridesPatch::default(),
}
}
pub fn with_overrides(mut self, overrides: CliOverridesPatch) -> Self {
self.overrides = overrides;
self
}
}
impl Default for FeaturesCommandRequest {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FeaturesEnableRequest {
pub feature: String,
pub overrides: CliOverridesPatch,
}
impl FeaturesEnableRequest {
pub fn new(feature: impl Into<String>) -> Self {
Self {
feature: feature.into(),
overrides: CliOverridesPatch::default(),
}
}
pub fn with_overrides(mut self, overrides: CliOverridesPatch) -> Self {
self.overrides = overrides;
self
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FeaturesDisableRequest {
pub feature: String,
pub overrides: CliOverridesPatch,
}
impl FeaturesDisableRequest {
pub fn new(feature: impl Into<String>) -> Self {
Self {
feature: feature.into(),
overrides: CliOverridesPatch::default(),
}
}
pub fn with_overrides(mut self, overrides: CliOverridesPatch) -> Self {
self.overrides = overrides;
self
}
}