CommunityCodierung & Entwicklunggithub.com

rust-qc

Verwenden Sie diese Fähigkeit immer dann, wenn Ihre Antwort Rust-Code oder Cargo/Clipy/rustfmt-Konfigurationen oder eine Bewertung von vorhandenem Rust-Code enthalten wird.

Was ist rust-qc?

Diese Fähigkeit standardisiert die Rust-Code-Erstellung, -Änderung und -Prüfung, indem sie bewährte Verfahren aus dem Rust Style Guide, den Rust API Guidelines, Microsofts Pragmatic Rust Guidelines (2026.6), Googles Rust Style Guide und den Praktiken beliebter Rust-Projekte wie memchr, jiff, ripgrep, fd und dua-cli durchsetzt. Sie unterstützt drei Modi: **Erstellen** für neue Funktionen/Typen/Kisten, **Ändern** für bestehenden Code und **Prüfen** für Code-Reviews und Audits. Die Fähigkeit priorisiert die Projekt-spezifischen Regeln (z. B. aus `rustfmt.toml`, `clippy.toml`, `CONTRIBUTING.md`) und folgt strikten, nicht verhandelbaren Regeln zur Formatierung, Code-Soundness, Fehlerbehandlung, Dokumentation und Testabdeckung. Sie integriert sich nahtlos in Cargo-Workflows und stellt sicher, dass alle Änderungen die Projekteinrichtung respektieren, Plattform-Gates berücksichtigen und eine Basislinie über `scripts/check.sh` validieren, bevor und nachdem Änderungen vorgenommen werden.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/coryj627/rust-qc/tree/main/.agents/skills/rust-qc

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Rust-Qualitätskontrolle (QC)

Diese Fähigkeit legt einen einheitlichen Standard für Rust-Code fest und wendet ihn in drei Modi an. Die Regeln stammen aus dem Rust Style Guide, den Rust API Guidelines, Microsofts Pragmatic Rust Guidelines (2026.6), Googles Rust Style Guide sowie den Praktiken, die in memchr, jiff, ripgrep, fd und dua-cli sichtbar sind. Wo diese Quellen widersprüchlich sind, dokumentiert references/precedence.md die Entscheidung, sodass Sie sie nie wieder neu verhandeln müssen.

Schritt 1: Kontext herstellen (alle Modi)

Führen Sie dies durch, bevor Sie Code schreiben oder bewerten. Stoppen Sie und melden Sie, wenn eine Vorbedingung fehlschlägt; raten Sie nicht um eine fehlende Toolchain oder ein fehlendes Manifest herum.

  1. Finden Sie die Kistenwurzel (die nächste Cargo.toml). Notieren Sie, ob es sich um einen Workspace, eine Bibliothek, eine Binärdatei oder beides handelt, und ob sie veröffentlicht ist (publish = false oder nur innerhalb des Workspaces oder über FFI konsumiert bedeutet intern).
  2. Lesen Sie zuerst die eigenen Regeln des Projekts, da sie die Standardeinstellungen dieser Fähigkeit überschreiben: rustfmt.toml oder .rustfmt.toml, clippy.toml, [lints] und [workspace.lints] in Cargo.toml, edition, rust-version (MSRV), rust-toolchain.toml, CONTRIBUTING.md, AGENTS.md oder CLAUDE.md sowie alle AI_POLICY.md. Wenn AI_POLICY.md oder CONTRIBUTING.md KI- oder Agentenbeiträge einschränkt, informieren Sie den Benutzer, bevor Sie Änderungen für dieses Repository erstellen.
  3. Klassifizieren Sie den Code als Bibliothek oder Anwendung. API-Entwurfsregeln sind bindend für Bibliotheken und starke Empfehlungen für Anwendungen, die Direktheit vor Allgemeinheit bevorzugen sollten.
  4. Notieren Sie die Plattformen. Wenn rust-toolchain.toml Ziele auflistet oder der Code stark mit #[cfg(windows)]-artigen Toren für eine andere Plattform als diesen Host versehen ist, führen Sie das Gate auch mit --target <dreifach> aus (es lintet und dokumentiert für dieses Ziel; Tests werden übersprungen). Warnungen wie dead code, die nur auf dem Host aufgrund von Plattform-Gates erscheinen, sind Host-Artefakte, keine Befunde.
  5. Führen Sie scripts/check.sh <kistenwurzel> einmal aus, um die Basislinie aufzuzeichnen. Sie benötigen sie, um Ihre eigenen Regressionen von bereits bestehenden Schulden zu unterscheiden. Verwenden Sie --features "<liste>" anstelle des standardmäßigen --all-features, wenn die Kiste sich gegenseitig ausschließende Funktionen hat.

Installieren Sie keine Toolchains, Komponenten oder Werkzeuge (nightly, Miri, cargo-hack) und verwenden Sie das Netzwerk nur zum Abrufen von Kisten, es sei denn, der Benutzer fordert dies an. Wenn eine Prüfung etwas Vermisstes benötigt, sagen Sie es und empfehlen Sie es.

Schritt 2: Den Modus wählen

Erstellen, wenn der Benutzer neue Funktionen, Methoden, Typen, Module oder Kisten wünscht. Befolgen Sie „Code erstellen" weiter unten.

Ändern, wenn der Benutzer vorhandenen Code geändert haben möchte: eine Funktion, Verbesserung, Fehlerbehebung, Refaktorisierung oder Behebung von Prüfungsbefunden. Befolgen Sie „Code ändern" weiter unten.

Prüfen, wenn der Benutzer vorhandenen Code überprüft, bewertet oder geprüft haben möchte, wobei Probleme identifiziert und Korrekturen vorgeschlagen werden. Befolgen Sie „Code prüfen" weiter unten. Prüfen ändert keinen Code, es sei denn, der Benutzer fordert dies an; es erstellt Befunde.

Eine Anfrage kann Modi umfassen („Prüfen Sie dieses Modul und beheben Sie, was Sie finden"). Führen Sie zuerst die Prüfung durch, berichten Sie, wechseln Sie dann zum Ändern für die Korrekturen.

Unverhandelbare Regeln

Diese gelten in jedem Modus. Der vollständige Regelsatz mit IDs befindet sich in den am Ende aufgeführten Referenzdateien.

  • Formatierung ist rustfmts Aufgabe. Formatieren Sie niemals von Hand gegen rustfmt. Fügen Sie niemals #[rustfmt::skip] hinzu, außer für bewusste Ausrichtung (Tabellen, Matrizen) oder generierten Code.
  • Code ist korrekt. Sicherer Code darf kein undefiniertes Verhalten verursachen können. Jeder unsafe-Block hat einen direkt darüberstehenden // SAFETY:-Kommentar, der erklärt, warum jede Vorbedingung gilt. Jede unsafe fn und jedes unsafe trait hat einen # Sicherheit-Dokumentationsabschnitt. Verwenden Sie unsafe nur für FFI, einen benchmarkten Leistungsbedarf oder eine neuartige Abstraktion und niemals, um Send, Sync oder Lebensdauern zu umgehen. Siehe references/unsafe.md.
  • Fehler versus Paniken. Wiederherstellbare Fehler, die durch Eingabe oder Umgebung verursacht werden, geben Result zurück (oder Option, wenn die Ursache offensichtlich ist). Erkannte Programmierfehler verursachen Paniken. Bibliothekscode verursacht niemals Paniken bei Aufrufereingaben, die vernünftigerweise ungültig sein könnten. Siehe references/errors.md.
  • Bibliotheksfehler ermöglichen Aufrufern die Verzweigung ohne Textparsen. Ein konkreter Fehlertyp mit einer kind()-Methode, die ein öffentliches #[non_exhaustive]-Enum zurückgibt, oder is_*()-Prädikaten. Private Felder sind richtig; ein privates Kind ohne Accessor ist ein Defekt. Nachrichten zeigen auf das verletzende Token und die Position und kopieren niemals die gesamte Eingabe.
  • Kein nacktes unwrap() im Produktionscode. Verwenden Sie ?, Pattern Matching oder expect("..."), dessen Nachricht angibt, warum die Invariante gilt. unwrap() ist in Tests in Ordnung. Dokumentationsbeispiele verwenden ? mit der versteckten Zeile # Ok::<(), Box<dyn std::error::Error>>(()).
  • Jede neue Abhängigkeit ist ein Kostenfaktor, einschließlich dev-dependencies. Fügen Sie eine nur hinzu, wenn sie echte Komplexität beseitigt oder Korrektheit bietet, die Sie vernünftigerweise nicht selbst schreiben können (Unicode-Case-Folding ist ein guter Grund; ein Property-Testing-Framework für einen 100-zeiligen Parser nicht). Sagen Sie in Ihrem Bericht, warum.
  • Struktur entspricht Größe. Erstellen Sie kein Modul für eine kleine Funktion und ihren Fehlertyp; ein Modul verdient seine Datei mit einem ausgeprägten Konzept und mehreren Elementen oder einigen hundert Zeilen.
  • Lint-Override verwenden #[expect(lint, reason = "...")], nicht #[allow], sodass veraltete Override an die Oberfläche kommen.
  • Öffentliche Elemente sind dokumentiert, der erste Satz ist eine Zeile von etwa 15 Wörtern, und Funktionen enthalten # Fehler, # Paniken und # Sicherheit-Abschnitte, wann immer sie zutreffen. Siehe references/documentation.md.
  • Öffentliche Typen implementieren Debug. Typen, die von Menschen gelesen werden sollen, implementieren auch Display.
  • Kommentare erklären das Warum, nicht das Was. Wenn ein Kommentar den Code wiederholt, löschen Sie ihn. ripgrep's Allokator-Kommentar in crates/core/main.rs ist das Vorbild: Entscheidung, Grund und die Bedingungen, unter denen er gilt.
  • Keine ASCII-Art-Diagramme oder Box-Zeichen in Kommentaren oder Dokumentationen. Beschreiben Sie Strukturen in Sätzen; Zeichnungen sind mit einem Screenreader nicht lesbar und verrotten, wenn sich Code ändert. (Team-Konvention, nicht upstream.)
  • Kein Design-Journal-Inhalt in Dokumentationen. Dokumentationen beschreiben aktuelles Verhalten, nicht wie der Code entstanden ist oder welche Richtlinien befolgt wurden.
  • Tests überprüfen Verhalten. Keine Tests, die eine Konstante wiederholen oder die Verzweigungen der Implementierung spiegeln.

Code erstellen

Arbeiten Sie von außen nach innen: Typen und Signaturen zuerst, dann Dokumentation, dann Implementierung, dann Tests. Das Schreiben des Dokumentationskommentars vor dem Rumpf ist der schnellste Weg, eine verwirrende API zu entdecken.

  1. Platzieren Sie es. Setzen Sie das Element in das Modul, das sein Konzept besitzt; in einer kleinen Kiste ist das oft lib.rs. Neue Module werden nach ihrem primären Typ benannt und nur erstellt, wenn der Code dies rechtfertigt (ORG-19). Siehe references/organization.md.
  2. Modellieren Sie mit Typen. Newtypes für Werte, die leicht zu verwechseln sind oder Invarianten tragen, mit Konstruktoren, die die Invariante durchsetzen. Ein enum anstelle eines bool-Parameters, dessen Bedeutung an der Aufrufstelle nicht offensichtlich ist. Benannte Felder gegenüber Tupeln. Machen Sie ungültige Zustände undarstellbar.
  3. Formen Sie die Signatur. Leihen Sie, was Sie nur lesen (&str, &[T], &Path, Option<&T>), übernehmen Sie das Eigentum nur, wenn Sie es speichern oder verbrauchen. In Bibliotheken akzeptieren Sie impl AsRef<Path> oder impl IntoIterator, wo es Reibung beseitigt; in Anwendungen behalten Sie konkrete Typen. Builder für Typen mit mehreren optionalen Einstellungen, die in build() validieren. Siehe references/api-design.md.
  4. Benennen Sie es. RFC 430-Schreibweise; as_ / to_ / into_-Konvertierungen; new, with_*, try_new-Konstruktoren; foo()-Getter. Keine Füllwörter (Manager, Service, Factory, Helper, Util) und kein Name, der mit einer vorhandenen Bedeutung in derselben Schnittstelle kollidiert (NAME-9).
  5. Dokumentieren Sie es gemäß references/documentation.md, einschließlich eines lauffähigen Beispiels für öffentliche Elemente und der Einheit jeder Position oder Länge, die Sie zurückgeben.
  6. Implementieren Sie es. Funktionen mit einem einzigen Zweck. Eine einfache for-Schleife über eine Kombinator-Kette, sobald die Kette Bedingungen oder externen Zustand benötigt; Kombinatoren, wenn sie handgeschriebene Logik ersetzen (any, position, sum). Typannotationen dort, wo die Inferenz einen Leser raten lassen würde. Menschlicher Text erhält Unicode-bewusste Behandlung: Groß-/Kleinschreibung ohne Berücksichtigung verwendet Unicode-Case-Folding oder dokumentiert seine Lücken (API-27).
  7. Behandeln Sie Fehler gemäß references/errors.md: in Bibliotheken ein konkreter Fehlertyp mit einem öffentlichen Kind oder Prädikaten; in Anwendungen anyhow mit .context().
  8. Testen Sie es gemäß references/testing.md: Inline-Komponententests, Integrationstests unter tests/ und breite Invariantenprüfungen, die keine neuen Abhängigkeiten benötigen (zählen Sie kurze Eingaben auf oder eine gesetzte Schleife gegen eine naive Referenz).
  9. Überprüfen Sie mit dem untenstehenden Gate.

Code ändern

Das Ziel ist die kleinste korrekte Änderung, die den berührten Code mindestens so klar hinterlässt, wie Sie ihn vorgefunden haben.

  1. Lesen Sie vor dem Bearbeiten. Lesen Sie die gesamte Funktion, ihre Aufrufer, ihre Tests und die benachbarte API. Identifizieren Sie lokale Konventionen (Importstil, Fehlertyp, Dokument-Überschriftenstil wie # Beispiel versus # Beispiele, Zeilenbreite, Dichte, Parameter- und Schlüsselnamen) und passen Sie sich ihnen an, auch wenn diese Standardwerte der Fähigkeit abweichen.
  2. Fehlerbehebungen beginnen mit einem fehlschlagenden Test, der die Fehlerklasse abdeckt. Reproduzieren Sie die gemeldete Eingabe und fügen Sie dann die benachbarten Fälle hinzu, die dieselbe Grundursache verursacht (mehr Elemente, andere Reihenfolgen, Kombinationen). Beobachten Sie ihr Fehlschlagen, beheben Sie die Grundursache, beobachten Sie ihr Bestehen. Wenn das Projekt Regressionstests an einem Ort aufbewahrt (ripgrep's tests/regression.rs), fügen Sie Ihre dort hinzu.
  3. Beheben Sie die Ursache, nicht das Symptom. Ein neues unwrap_or_default(), clone() oder eine frühe Rückgabe, die einen Fehler unterdrückt, ist keine Korrektur, es sei denn, Sie können erklären, warum der ursprüngliche Pfad falsch war. Fügen Sie einen einzeiligen Kommentar an der Korrektur ein, wenn der Grund aus dem Code nicht offensichtlich ist.
  4. Bleiben Sie chirurgisch. Benennen Sie Code, den Sie nicht bearbeiten sollten, nicht um, ordnen Sie ihn nicht neu und formatieren Sie ihn nicht neu. Listen Sie stattdessen nicht zusammenhängende Probleme für den Benutzer auf, anstatt sie stillschweigend zu beheben.
  5. Halten Sie öffentliche APIs und ABIs stabil, es sei denn, der Benutzer hat eine bahnbrechende Änderung genehmigt. Das Hinzufügen eines Feldes zu einer öffentlichen Struktur mit öffentlichen Feldern, einer Variante zu einem erschöpfenden öffentlichen Enum, einer erforderlichen Trait-Methode oder die Änderung eines FFI-Vertrags ist bahnbrechend.
  6. Aktualisieren Sie Dokumentation und Tests mit dem Code. Eine geänderte Signatur oder ein geändertes Verhalten bedeutet geänderte # Fehler, # Paniken, Beispiele und Tests in derselben Änderung.
  7. Formatierung: Wenn die Basislinie rustfmt-sauber war, führen Sie cargo fmt aus. Wenn nicht, formatieren Sie nur das, was Sie geändert haben, und informieren Sie den Benutzer. Wenn rustfmt.toml Nightly-only-Optionen verwendet (stabiles rustfmt warnt, dass sie „nur im nightly-Kanal verfügbar" sind), ist der Standard des Projekts cargo +nightly fmt; verwenden Sie es, wenn installiert, und formatieren Sie andernfalls nichts automatisch und sagen Sie dies, da stabiles rustfmt Code gegen die Projekteinstellungen umschreiben würde.
  8. Behebung aus einer Prüfung: Beheben Sie Befunde nach Schweregrad, einen Befund pro logischer Änderung, und benennen Sie den Befund in Ihrer Zusammenfassung.
  9. Überprüfen Sie mit dem untenstehenden Gate und bestätigen Sie, dass Sie keine neuen Warnungen relativ zur Basislinie eingeführt haben, auf jedem Ziel, das Sie in Schritt 1 überprüft haben.

Code prüfen

  1. Führen Sie scripts/check.sh --audit <kistenwurzel> aus (plus --target gemäß Schritt 1). Der --audit-Durchlauf meldet mit öffentlicher API-Erreichbarkeit, undokumentiertes unsafe, fehlende Dokumentation und # Fehler/# Paniken-Abschnitte, unwrap außerhalb von Tests, #[allow] ohne Grund, dbg!/todo!, Glob-Imports und Assertionen ohne Nachrichten. Melden Sie diese Hygieneergebnisse kompakt: einen Minor-Befund pro Kategorie (Dokumentation, Debug, SAFETY-Kommentare, Lint-Konfiguration), jeweils mit einer Anzahl und den wenigen Instanzen, die am wichtigsten sind. Ein Gate-Schritt, der nur fehlschlägt, weil die Toolchain hier neuer ist als die, die das CI des Projekts oder rust-toolchain.toml verwendet, ist Toolchain-Drift: ein Minor-Befund, kein Major.

  2. Führen Sie python3 -I scripts/audit_scan.py <kistenwurzel> für das aus, was clippy nicht sehen kann: Glob-Re-Exports, Weasel-Wort-Typnamen, ASCII-Art-Kommentare, Design-History-Dokumentationen, Parametertabellen, bare TODOs, leere expect-Nachrichten und Print-Makros in Bibliothekscode. Bestätigen Sie jeden Treffer durch Lesen des Codes; verwerfen Sie Fehlalarme.

  3. Prüfen Sie das Verhalten so, wie Benutzer es antreffen. Hier werden die meisten benutzerseitigen Fehler in echten Kisten gefunden, also verbringen Sie den Großteil der Prüfung hier und in Schritt 5. Lesen Sie die Dokumentation, Spezifikation und Tests der Kiste, um die Eingabefunktionen aufzulisten, die sie zu verarbeiten beansprucht. Erstellen Sie für jede eine kleine realistische Eingabe, die die vorhandenen Tests nicht abdecken, führen Sie sie durch die öffentliche API aus einer Wegwerfkiste außerhalb des Workspaces und vergleichen Sie die Ausgabe mit dem, was ein Benutzer erhalten sollte. Decken Sie die Funktionen ab, die das Format zulässt, die Fixtures jedoch überspringen:

    • geerbte, indirekte oder standardmäßige Werte
    • Duplikate
    • optionale oder versteckte Teile
    • leichte Schäden, die andere Werkzeuge tolerieren
    • nicht-ASCII-Text und Legacy-Kodierungen
    • große, aber legitime Größen

    Melden Sie jedes bestätigte Problem mit der Eingabe, die es zeigt.

  4. Testen Sie nicht vertrauenswürdige Eingaben. Füttern Sie jede öffentliche Funktion, die nicht vertrauenswürdige Bytes oder Text parst, mit jeder kurzen Eingabe über einem relevanten Alphabet oder einigen Millionen gesäten zufälligen Mutationen und fangen Sie Paniken ab. Versuchen Sie auch handgefertigte Strukturen, die die Arbeit schneller wachsen lassen als die Eingabegröße (gemeinsame oder rekursive Referenzen, tiefe Verschachtelung) unter einem Timeout.

  5. Lesen Sie den Code auf Dinge, die Werkzeuge nicht beurteilen können: Korrektheit jedes unsafe-Blocks, Fehlerdesign, API-Form, Modulgrenzen, Benennung, Testqualität und ob Kommentare das Warum erklären. Überprüfen Sie in Code, der mit dem Betriebssystem spricht, auch:

    • Paniken bei einem Syscall, I/O oder Umgebungsfehler (assert! oder unwrap auf einem Rückgabewert, eine nicht-UTF-8-Umgebungsvariable oder ein Passwd-Feld)
    • Code zwischen fork und exec (pre_exec-Closures) oder in einem Signalhandler, der allokiert, sperrt, formatiert, protokolliert oder beendet, was alles nicht async-signal-safe ist
    • durchgesickerte Dateideskriptoren oder Handles und Signale, die an eine Prozess-ID gesendet werden, die möglicherweise abgeholt und wiederverwendet wurde
    • verengende Casts und ungeprüfte Arithmetik bei Größen, Zählungen und Koordinaten

    Verwenden Sie references/audit-checklist.md.

  6. Berichten Sie im untenstehenden Format. Schlagen Sie für jeden Befund eine konkrete Korrektur vor.

Die Schritte 1 und 2 sind eine schnelle Basislinie, nicht die Prüfung: Verbringen Sie nicht mehr als etwa ein Fünftel der Zeit damit. Eine Prüfung, die hauptsächlich Lint-, Dokumentations- und Stilbefunde auflistet, ohne mindestens einen Benutzerverhaltensfehler (Schritt 3) oder Korrektheitsproblem (Schritt 5) zu finden, ist nicht gründlich genug.

Gate (alle Modi)

Eine Kistenprüfung, die nicht mindestens einen Benutzerverhaltensfehler (Schritt 3) oder Korrektheitsproblem (Schritt 5) findet, ist nicht gründlich genug.

Wenn die Prüfung fehlschlägt, stoppen Sie. Berichten Sie das Problem dem Benutzer.

Verwandte Skills