code-simplifier
rtk-ai/rtk
Simplify Rust code in RTK by applying idiomatic patterns without changing behavior.
What is code-simplifier?
A code review skill that detects over-engineering, unnecessary allocations, and verbose patterns in Rust code. It applies Rust idioms like iterator chains, early returns, and proper Option/Result chaining while respecting RTK's mandatory constraints (lazy_static regexes, .context() chains, fallback handling).
- Converts manual loops to iterator chains and functional patterns
- Replaces verbose string building with join() and format!()
- Simplifies nested Option/Result matching with and_then() and unwrap_or()
- Suggests struct destructuring to reduce repeated field access
- Refactors deeply nested conditionals to early returns
- Removes redundant clones and unnecessary allocations
How to install code-simplifier
npx skills add null --skill code-simplifierHow to use code-simplifier
- 1.Trigger the skill with phrases like 'simplify', 'too verbose', 'over-engineered', or 'make this idiomatic'
- 2.Review the suggested simplifications, which preserve RTK constraints (lazy_static, .context(), fallback handling)
- 3.Accept changes that apply iterator chains, early returns, and proper Option/Result chaining
- 4.Run cargo fmt, cargo clippy, and cargo test to verify no regressions
- 5.Verify lazy_static regexes remain in static blocks and unwrap() only appears in init-time or test code
Use cases
- Refactoring RTK filter implementations to use iterator chains instead of manual loops
- Simplifying error handling chains that use nested match statements
- Reducing verbosity in string processing without breaking mandatory .context() patterns
- Converting imperative loops to functional style while preserving exit code propagation
- Cleaning up struct field access patterns in command-line argument handling
- Rust developers working on RTK projects
- Code reviewers looking to enforce idiomatic Rust patterns
- Teams maintaining command-line tools with strict error-handling requirements
code-simplifier FAQ
No. The skill respects RTK's mandatory .context() on every ? operator, even though it looks verbose. This is a project constraint that is never simplified away.
No. Regex initialization inside lazy_static! blocks is never moved into functions, even if it appears simpler. The skill preserves this constraint.
The fallback match arm (Err(e) => { eprintln!(...); raw_output }) is never removed, even if it looks like dead code. It's the safety net for RTK filters.
No. Exit code propagation and std::process::exit(code) calls are never simplified to Ok(()), even though they might appear redundant.
Run cargo fmt --all, cargo clippy --all-targets, and cargo test. Also grep for Regex::new (should only be in lazy_static!) and .unwrap() (should only be in init-time or #[cfg(test)] blocks).
Full instructions (SKILL.md)
Source of truth, from rtk-ai/rtk.
name: code-simplifier description: Review RTK Rust code for idiomatic simplification. Detects over-engineering, unnecessary allocations, verbose patterns. Applies Rust idioms without changing behavior. triggers:
- "simplify"
- "too verbose"
- "over-engineered"
- "refactor this"
- "make this idiomatic" allowed-tools:
- Read
- Grep
- Glob
- Edit effort: low tags: [rust, simplify, refactor, idioms, rtk]
RTK Code Simplifier
Review and simplify Rust code in RTK while respecting the project's constraints.
Constraints (never simplify away)
lazy_static!regex — cannot be moved inside functions even if "simpler".context()on every?— verbose but mandatory- Fallback to raw command — never remove even if it looks like dead code
- Exit code propagation — never simplify to
Ok(()) #[cfg(test)] mod tests— never remove test modules
Simplification Patterns
1. Iterator chains over manual loops
// ❌ Verbose
let mut result = Vec::new();
for line in input.lines() {
let trimmed = line.trim();
if !trimmed.is_empty() && trimmed.starts_with("error") {
result.push(trimmed.to_string());
}
}
// ✅ Idiomatic
let result: Vec<String> = input.lines()
.map(|l| l.trim())
.filter(|l| !l.is_empty() && l.starts_with("error"))
.map(str::to_string)
.collect();
2. String building
// ❌ Verbose push loop
let mut out = String::new();
for (i, line) in lines.iter().enumerate() {
out.push_str(line);
if i < lines.len() - 1 {
out.push('\n');
}
}
// ✅ join
let out = lines.join("\n");
3. Option/Result chaining
// ❌ Nested match
let result = match maybe_value {
Some(v) => match transform(v) {
Ok(r) => r,
Err(_) => default,
},
None => default,
};
// ✅ Chained
let result = maybe_value
.and_then(|v| transform(v).ok())
.unwrap_or(default);
4. Struct destructuring
// ❌ Repeated field access
fn process(args: &MyArgs) -> String {
format!("{} {}", args.command, args.subcommand)
}
// ✅ Destructure
fn process(&MyArgs { ref command, ref subcommand, .. }: &MyArgs) -> String {
format!("{} {}", command, subcommand)
}
5. Early returns over nesting
// ❌ Deeply nested
fn filter(input: &str) -> Option<String> {
if !input.is_empty() {
if let Some(line) = input.lines().next() {
if line.starts_with("error") {
return Some(line.to_string());
}
}
}
None
}
// ✅ Early return
fn filter(input: &str) -> Option<String> {
if input.is_empty() { return None; }
let line = input.lines().next()?;
if !line.starts_with("error") { return None; }
Some(line.to_string())
}
6. Avoid redundant clones
// ❌ Unnecessary clone
fn filter_output(input: &str) -> String {
let s = input.to_string(); // Pointless clone
s.lines().filter(|l| !l.is_empty()).collect::<Vec<_>>().join("\n")
}
// ✅ Work with &str
fn filter_output(input: &str) -> String {
input.lines().filter(|l| !l.is_empty()).collect::<Vec<_>>().join("\n")
}
7. Use if let for single-variant match
// ❌ Full match for one variant
match output {
Ok(s) => process(&s),
Err(_) => {},
}
// ✅ if let (but still handle errors in RTK — don't silently drop)
if let Ok(s) = output {
process(&s);
}
// Note: in RTK filters, always handle Err with eprintln! + fallback
RTK-Specific Checks
Run these after simplification:
# Verify no regressions
cargo fmt --all && cargo clippy --all-targets && cargo test
# Verify no new regex in functions
grep -n "Regex::new" src/<file>.rs
# All should be inside lazy_static! blocks
# Verify no new unwrap in production
grep -n "\.unwrap()" src/<file>.rs
# Should only appear inside #[cfg(test)] blocks
What NOT to Simplify
lazy_static! { static ref RE: Regex = Regex::new(...).unwrap(); }— the.unwrap()here is acceptable, it's init-time.context("description")?chains — verbose but required- The fallback match arm
Err(e) => { eprintln!(...); raw_output }— looks redundant but is the safety net std::process::exit(code)at end of run() — looks like it could beOk(())but it isn't
Related skills
More from rtk-ai/rtk and the wider catalog.
design-patterns
Rust design patterns for RTK CLI filter modules: Newtype, Builder, RAII, Trait Objects, State Machine.
rtk-tdd
Enforces Red-Green-Refactor TDD discipline for Rust with idiomatic test patterns and automated workflow.

create-branch
Create and checkout git branches with smart validation and GitHub issue integration

asc-id-resolver
Resolve App Store Connect IDs from human-friendly names for use in other asc commands.

asc-release-flow
Validate app readiness and drive App Store submission with asc, handling metadata, builds, IAP, subscriptions, and privacy checks.

asc-submission-health
Validate App Store submission readiness, submit versions, and monitor review status with asc commands.