This skill teaches you to write Rust code in the style of the OpenAI Codex codebase - a production CLI/agent system with 50 crates and 787 Rust files.
Key Characteristics
-
Edition 2024 with strict Clippy configuration
-
Zero unwrap/expect in non-test code (enforced at workspace level)
-
Tokio async runtime with proper Send + Sync bounds
-
thiserror for library errors, anyhow for application code
-
Flat workspace structure with centralized dependencies
When to Apply
Apply this skill when:
-
Building CLI tools or agent systems in Rust
-
Writing async Rust with Tokio
-
Designing Rust workspace organization
-
Implementing error handling patterns
-
Working on production Rust codebases
Quick Reference
Critical Rules (Must Follow)
| err-no-unwrap
| Never use unwrap() in non-test code
| err-no-expect
| Avoid expect() in library code
| err-thiserror-domain | Use thiserror for domain errors
| err-context-chain
| Add context to errors with .context()
Error Handling
| err-anyhow-application | Use anyhow::Result for entry points
| err-from-derive | Use #[from] for error conversion
| err-transparent | Use #[error(transparent)] for wrapped errors
| err-structured-variants | Include relevant data in error variants
| err-io-result | Use std::io::Result for I/O functions
| err-map-err-conversion | Use map_err for error conversion
| err-doc-errors | Document error conditions
Organization
| org-workspace-flat | Flat workspace with utils subdirectory
| org-crate-naming | kebab-case directories, project prefix
| org-module-visibility | Use pub(crate) for internal APIs
| org-test-common-crate | Shared test utilities crate
| org-integration-tests-suite | Tests in suite directory
| org-feature-modules | Feature-based module organization
| org-handlers-subdir | Handlers in dedicated subdirectory
| org-errors-file | Errors in dedicated file
Component Patterns
| mod-derive-order | Consistent derive macro ordering
| mod-async-trait-macro | Use #[async_trait] for async traits
| mod-trait-bounds | Send + Sync + 'static for concurrent traits
| mod-extension-trait-suffix | Ext suffix for extension traits
| mod-builder-pattern | Builder pattern for complex config
| mod-type-alias-complex | Type aliases for complex generics
| mod-impl-block-order | Consistent impl block ordering
| mod-generic-constraints | Where clauses for complex bounds
| mod-newtype-pattern | Newtypes for type safety
| mod-struct-visibility | Private fields with public constructor
| mod-serde-rename | Serde rename for wire format
| mod-jsonschema-derive | JsonSchema for API types
Naming Conventions
| name-async-no-suffix | No _async suffix for async functions
| name-try-prefix-fallible | try_ prefix for fallible constructors
| name-with-prefix-builder | with_ prefix for builder methods
| name-handler-suffix | Handler suffix for handlers
| name-error-suffix | Error suffix for error types
| name-result-type-alias | Crate-specific Result alias
| name-const-env-var | _ENV_VAR suffix for env constants
| name-request-response | Request/Response type pairing
| name-options-suffix | Options suffix for config bundles
| name-info-suffix | Info suffix for read-only data
| name-provider-suffix | Provider suffix for services
| name-client-suffix | Client suffix for API clients
| name-manager-suffix | Manager suffix for lifecycle mgmt
| name-bool-is-prefix | is_/has_/should_ for booleans
| name-plural-collections | Plural names for collections
Style
| style-import-granularity | One item per use statement
| style-deny-stdout | Deny stdout/stderr in libraries
| style-inline-format-args | Inline format arguments
| style-module-docs | Module-level documentation
| style-expect-reason | #[expect] with reason for lints
| style-cfg-test-module | Unit tests in mod tests
Cross-Crate
| cross-workspace-lints | Workspace-level lint config
| cross-workspace-deps | Centralized dependency versions
Example: Proper Error Handling
use thiserror::Error;
use anyhow::Context;
// Domain error with thiserror
#[derive(Debug, Error)]
pub enum ConfigError {
#[error("failed to read config file: {path}")]
ReadFailed {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error(transparent)]
Parse(#[from] toml::de::Error),
}
// Library function returns domain error
pub fn load_config(path: &Path) -> Result<Config, ConfigError> {
let content = fs::read_to_string(path)
.map_err(|source| ConfigError::ReadFailed {
path: path.to_owned(),
source,
})?;
toml::from_str(&content).map_err(Into::into)
}
// Application code uses anyhow with context
fn main() -> anyhow::Result<()> {
let config = load_config(Path::new("config.toml"))
.context("failed to load configuration")?;
run(config).await
}
Source
Patterns extracted from OpenAI Codex (codex-rs/ subdirectory) - a production Rust codebase with 50 crates and 787 Rust files.