rust-coding-guidelines | Skill Performance & Reviews | TopRankSkills

TopRank Skills

Home / Skills / tools / rust-coding-guidelines

rust-coding-guidelines

maintained by zerx-lab

star 34 account_tree 0 verified_user MIT License
bolt View GitHub

name: rust-coding-guidelines description: Rust and GPUI coding standards. MUST LOAD before writing any Rust code. Covers error handling, naming conventions, async patterns, file organization, and GPUI-specific rules. This skill is MANDATORY for all Rust work in this project.

Rust Coding Guidelines

IMPORTANT: This skill contains mandatory coding rules for this project. Violations will cause code review failures.

Core Principles

  1. Prioritize correctness and clarity - Speed/efficiency are secondary unless specified
  2. Avoid creative additions - Unless explicitly requested
  3. Prefer existing files - Unless creating a new logical component
  4. Comments explain "why", not "what" - No organizational/summary comments

Error Handling (CRITICAL)

NEVER use unwrap()

// WRONG
let value = option.unwrap();
let result = operation().unwrap();

// CORRECT - propagate with ?
let value = option.ok_or_else(|| anyhow::anyhow!("Missing value"))?;
let result = operation()?;

// CORRECT - explicit handling
match option {
    Some(value) => { /* use value */ }
    None => { /* handle missing */ }
}

NEVER silently discard errors

// WRONG - silently discards error
let _ = client.request(url).await?;

// CORRECT - propagate
client.request(url).await?;

// CORRECT - log but continue
operation().log_err();

// CORRECT - explicit handling
if let Err(e) = operation() {
    eprintln!("Operation failed: {}", e);
}

ALWAYS propagate errors to UI

fn save_file(&mut self, cx: &mut Context<Self>) {
    cx.spawn(async move |this, cx| {
        match write_file(path, data).await {
            Ok(()) => {
                this.update(&mut *cx, |view, cx| {
                    view.status = "Saved successfully".into();
                    cx.notify();
                })?;
            }
            Err(e) => {
                this.update(&mut *cx, |view, cx| {
                    view.error = Some(format!("Save failed: {}", e));
                    cx.notify();
                })?;
            }
        }
        Ok(())
    }).detach_and_log_err(cx);
}

Indexing Safety

Be careful with indexing operations - they may panic if indexes are out of bounds.

// WRONG - may panic
let item = items[index];

// CORRECT - safe access
let item = items.get(index).ok_or_else(|| anyhow::anyhow!("Index out of bounds"))?;

Variable Naming

Use full words (NO abbreviations)

// WRONG
let q = VecDeque::new();
let cnt = 0;
let btn = Button::new();

// CORRECT
let queue = VecDeque::new();
let count = 0;
let button = Button::new();

Async Patterns

Variable Shadowing for Clones

Use variable shadowing to scope clones in async contexts:

// CORRECT pattern
executor.spawn({
    let task_ran = task_ran.clone();
    async move {
        *task_ran.borrow_mut() = true;
    }
});

File Organization

NEVER create mod.rs files

// WRONG
src/
  components/
    mod.rs       // Don't do this
    button.rs

// CORRECT
src/
  components.rs  // Module file
  components/
    button.rs

Library Root Paths

For crates, specify library root in Cargo.toml:

[lib]
path = "src/my_lib.rs"  # Instead of default lib.rs

GPUI-Specific Rules

Context Types

  • App - root context, access to global state
  • Context<T> - provided when updating Entity<T>, dereferences to App
  • AsyncApp / AsyncWindowContext - from cx.spawn, can be held across await points

Window Parameter

Window comes before cx when present:

impl Render for MyView {
    fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
        // window first, cx second
    }
}

Entity Operations

// Read
let view = entity.read(cx);

// Update (use inner cx!)
entity.update(cx, |view, inner_cx| {
    view.count += 1;
    inner_cx.notify(); // Use inner_cx, NOT outer cx!
});

// NEVER update while already updating
entity.update(cx, |view, cx| {
    entity.update(cx, |_, _| {}); // PANIC!
});

Testing Timers

In GPUI tests, use GPUI executor timers, NOT smol::Timer:

// WRONG - may cause "nothing left to run"
smol::Timer::after(duration).await;

// CORRECT
cx.background_executor().timer(duration).await;
// or
cx.background_executor.timer(duration).await; // in TestAppContext

Event Handlers

// Using cx.listener for callbacks
.on_click(cx.listener(|this: &mut Self, event, window, cx| {
    // this: &mut Self
    // event: click event
    // window: &mut Window
    // cx: &mut Context<Self>
}))

Notify After State Changes

fn update_state(&mut self, cx: &mut Context<Self>) {
    self.data = new_data;
    cx.notify(); // Required for UI update
}

EventEmitter

// Declare event type
impl EventEmitter<MyEvent> for MyView {}

// Emit in handler
cx.emit(MyEvent::ValueChanged(value));

Subscriptions

Store Subscription in struct fields - they auto-cancel when dropped:

struct Parent {
    child: Entity<Child>,
    _subscription: Subscription, // Keep alive
}

Project-Specific Rules

dbg!() and todo!() are DENIED

This project has Clippy rules that deny dbg!() and todo!() macros.

// WRONG - will fail clippy
dbg!(value);
todo!();

// Use proper logging or error handling instead

Workspace Dependencies

All dependencies must be declared in workspace Cargo.toml, sub-crates use .workspace = true:

# In sub-crate Cargo.toml
[dependencies]
gpui.workspace = true

Quick Reference Checklist

Before submitting code:

  • No unwrap() calls
  • No let _ = on fallible operations
  • No dbg!() or todo!()
  • Full variable names (no abbreviations)
  • No mod.rs files
  • cx.notify() after state changes
  • Errors propagate to UI
  • GPUI timers in tests (not smol)
  • Subscriptions stored in struct fields
  • Using inner cx in entity update closures

References

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!

Skill Details

GitHub Stars 34
GitHub Forks 0
Created Mar 2026
Last Updated 3 months ago
tools tools ide plugins

Related Skills

writing-skills
chevron_right
codex
chevron_right
smart-illustrator
chevron_right
collaborating-with-codex
chevron_right
code-review-router
chevron_right

Build your own?

Join 12,000+ developers contributing to the Claude ecosystem.