CommunityRedacción y edicióngithub.com

spnngl/agent-skills

Flujo de trabajo y modismos de Rust. Útil al escribir, revisar o refactorizar código Rust, o al editar Cargo.toml.

¿Qué es agent-skills?

Este skill está diseñado para agentes de IA (como Claude Code, Cursor o Codex) que trabajan con el lenguaje de programación Rust. Proporciona un flujo de trabajo estructurado en cinco pasos que guía al agente desde la orientación inicial en el proyecto hasta la autoevaluación final del diff. El skill enfatiza la codificación de invariantes en tipos de datos (‘make illegal states unrepresentable’), la preferencia por los modismos actuales del ecosistema Rust (como `LazyLock` sobre `lazy_static!`) y la verificación completa con `cargo check`, `cargo clippy` y `cargo test`. Incluye reglas detalladas sobre ownership, manejo de errores, panics, y dependencias, así como referencias a archivos complementarios para aspectos específicos como API pública, `unsafe` o pruebas. Al seguir esta guía, el agente puede garantizar que el código generado o revisado sea idiomático, seguro y compilable con las herramientas estándar de Rust.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/spnngl/agent-skills/tree/HEAD/skills/rust/rs-coding

Installed? Explore more Redacción y edición skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Codificación en Rust

Flujo de trabajo

  1. Orientación. Lee las fuentes de verdad del proyecto antes de escribir: rust-toolchain.toml, Cargo.toml (edition, rust-version, [lints], [workspace]), clippy.toml, rustfmt.toml, .cargo/config.toml, y la configuración de CI, justfile, Makefile, o xtask para los comandos de verificación canónicos. Lee el módulo que estás modificando y sus vecinos; reutiliza sus ayudantes, tipos de error y patrones. Terminado cuando: puedes nombrar la edición, la MSRV, la política de lints, cada entrada de disallowed-methods / disallowed-types, y los comandos de verificación del proyecto.

  2. Modela los tipos. Diseña los datos antes que el flujo de control, siguiendo Tipos. Si cambias la API pública de una biblioteca: lee references/api.md. Terminado cuando: cada invariante del que depende el cambio está codificado en un tipo, o mantenido por un expect cuyo mensaje lo nombra.

  3. Implementa en un bucle cerrado. Trabaja en pasos pequeños y ejecuta cargo check después de cada uno. Lee el diagnóstico completo: su línea help: suele nombrar la corrección, y rustc --explain E0502 expande un código de error. Para la API de una dependencia, lee su fuente en la versión bloqueada (Cargo.lock) bajo $CARGO_HOME/registry/src/. Los cambios masivos de nombre se realizan mediante el renombrado de rust-analyzer o ast-grep; cargo clippy --fix aplica sugerencias aplicables automáticamente. Corrección de errores: escribe la prueba de regresión primero y observa que se ponga roja. Terminado cuando: el cambio compila sin advertencias en las líneas que cambiaste, y cualquier prueba de regresión se puso roja antes de la corrección y verde después.

  4. Verifica. Ejecuta los comandos del proyecto del paso 1; de lo contrario:

    cargo fmt --all
    cargo clippy --workspace --all-targets --all-features -- -D warnings
    cargo test --workspace --all-features
    
    • Proyecto sin política [lints]: también ejecuta cargo clippy --all-targets -- -W clippy::pedantic y corrige los aciertos en las líneas que cambiaste.
    • Funcionalidades mutuamente excluyentes: reemplaza --all-features con cada conjunto de funcionalidades que CI pruebe.
    • cargo nextest omite doctests: añade cargo test --doc.
    • Documentación pública cambiada: RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features.
    • unsafe tocado: ejecuta references/unsafe.md.
    • Corrige los lints en la causa. Cuando la supresión sea correcta, limita #[expect(clippy::lint_name, reason = "...")] al elemento más pequeño. Terminado cuando: cada comando sale con 0, las líneas que cambiaste no generan advertencias, y cada nueva supresión lleva un reason.
  5. Autorevisa el diff. Vuelve a leer el git diff completo, no tu memoria del mismo, contra Reglas y las reglas de cada archivo de referencia cuya rama toque el diff. Terminado cuando: cada hunk es necesario para la tarea, el código prototipo y dbg! / todo! han desaparecido, los comentarios de documentación coinciden con el comportamiento, y cada regla aplicable se cumple para cada hunk.

Revisando código de otra persona: ejecuta el paso 1, ejecuta los comandos del paso 4 cuando puedas, luego aplica el paso 5 a su diff. Reporta cada hallazgo como path:line, la regla y la corrección.

Reglas

Ownership

  • Toma prestado en parámetros: &str, &[T], &Path, &T. Toma String, Vec<T> o T por valor solo cuando la función los almacena o consume.
  • Cada .clone() se gana su lugar: el destinatario necesita ownership, o el valor es un handle barato (Arc::clone(&handle)).
  • Cuando el borrow checker se opone, reestructura primero: acorta el préstamo, toma prestados campos disjuntos por separado, std::mem::take / replace, índices en un Vec. El ownership mutable compartido (Rc<RefCell<_>>, Arc<Mutex<_>>) es el último recurso.
  • Devuelve impl Iterator<Item = T> cuando el llamante solo itera.

Tipos

  • Haz que los estados ilegales no sean representables: un enum que lleva datos por estado, en lugar de banderas bool más campos Option; newtypes para IDs, unidades y valores validados (struct Port(NonZeroU16)).
  • Analiza, no valides: convierte la entrada no confiable una vez en el límite (TryFrom, FromStr, #[serde(try_from = "Raw")]) y pasa el tipo analizado hacia adentro.
  • Haz matching exhaustivo en enums que posees. Un brazo _ es correcto solo cuando una variante futura debería tomar esa rama también.
  • Convierte enteros con From / TryFrom; as trunca e invierte el signo silenciosamente.

Errores y panics

  • Biblioteca: un enum thiserror por dominio de fallo. Binario: anyhow::Result con .context(...).
  • Los panics significan errores. unwrap() vive en pruebas; el código de producción usa ? o expect("...") indicando el invariante que hace imposible el fallo.

Modismos actuales

Los patrones antiguos dominan los datos de entrenamiento. Prefiere la forma actual cuando rust-version lo permita; los nuevos crates usan edition = "2024". clippy::incompatible_msrv detecta solo APIs nuevas de std; las características del lenguaje y Cargo necesitan cargo +<msrv> check.

PreferirSobreDesde
std::sync::LazyLock, OnceLocklazy_static!, once_cell1.80, 1.70
let Some(x) = opt else { return ... };match + retorno temprano1.65
if let Some(x) = a && x > 0if let anidado1.88, edition 2024
async fn nativo en traits#[async_trait], aún necesario para dyn Trait1.75
closures `async{}, bounds AsyncFn`
#[expect(lint, reason = "...")]#[allow(lint)]1.81
&raw const x, &raw mut xptr::addr_of!1.82
opt.is_some_and(f), opt.is_none_or(f)map_or(false, f), map_or(true, f)1.70, 1.82
std::hint::black_boxcriterion::black_box1.66
[lints] en Cargo.toml para política compartida#![warn(...)] en cada raíz de crate1.74
directivas cargo:: de build-scriptcargo:1.77

Documentación y comentarios

  • Los elementos públicos obtienen docs ///: # Errors en funciones que pueden fallar, # Panics en funciones que pueden entrar en pánico, ejemplos como doctests usando ?.
  • Los comentarios explican por qué; el código muestra qué.

Dependencias

  • Reutiliza lo que el workspace ya depende ([workspace.dependencies], cargo tree -i <crate>), y prefiere std cuando cubre la necesidad.
  • Añade con cargo add (consciente de MSRV), habilitando solo las funcionalidades que uses.

Referencias

Carga la que coincida con la rama en la que estás:

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

Skills relacionados