mirror of
https://github.com/openai/codex.git
synced 2026-04-29 02:41:12 +03:00
2.7 KiB
2.7 KiB
DOs
- Align UI text with config: Use a single source of truth by deriving
DisplayandSerialize/Deserializeon the enum with kebab-case.
use serde::{Deserialize, Serialize};
use strum_macros::Display;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Serialize, Deserialize, Display)]
#[serde(rename_all = "kebab-case")]
#[strum(serialize_all = "kebab-case")]
pub enum AskForApproval {
#[default]
#[serde(rename = "untrusted")]
#[strum(serialize = "untrusted")]
UnlessTrusted,
OnFailure,
Never,
}
- Render policies via
Display: Show the kebab-case value withto_string()(orformat!("{}", ...)) in summaries and TUI.
("approval", config.approval_policy.to_string())
// or
("approval", format!("{}", config.approval_policy))
- Override per-variant when needed: Explicitly rename variants whose desired label isn’t the kebab-case of the Rust identifier.
#[serde(rename = "untrusted")]
#[strum(serialize = "untrusted")]
UnlessTrusted,
- Keep changes centralized: Put naming logic on the enum, not scattered across UI layers.
// Good: UI just uses Display everywhere
let approval = config.approval_policy.to_string();
- Verify and update snapshots when UI text changes: Regenerate and accept TUI snapshots that include the new strings.
cargo test -p codex-tui
cargo insta pending-snapshots -p codex-tui
cargo insta accept -p codex-tui
DON'Ts
- Don’t use Debug for user-facing strings:
{:?}exposes Rust variant names that don’t match config values.
// Bad: prints "UnlessTrusted"
("approval", format!("{:?}", config.approval_policy))
- Don’t use
serde_json::to_stringfor display: It adds quotes/JSON formatting and increases complexity.
// Bad: results in "\"untrusted\""
("approval", serde_json::to_string(&config.approval_policy).unwrap())
- Don’t duplicate mapping in the UI: Avoid hand-written matches or ad-hoc conversions in multiple files.
// Bad: scattered, easy to drift
let label = match config.approval_policy {
AskForApproval::UnlessTrusted => "untrusted",
AskForApproval::OnFailure => "on-failure",
AskForApproval::Never => "never",
};
- Don’t rely on implicit case conversion to match external spec: Handle exceptions like
UnlessTrusted→untrustedexplicitly.
// Bad: assumes kebab-case of identifier is correct
#[strum(serialize_all = "kebab-case")] // without per-variant override
// "UnlessTrusted" would become "unless-trusted" (wrong)
- Don’t leak internal names into UX: Users should see config-aligned values, not Rust identifiers.
// Bad UX: shows "OnFailure" instead of "on-failure"
format!("{:?}", AskForApproval::OnFailure);