بنقرة واحدة
rust-development
Idiomatisk Rust-utvikling med cargo, clippy, error handling, async/tokio, unsafe og testing
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Idiomatisk Rust-utvikling med cargo, clippy, error handling, async/tokio, unsafe og testing
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Generer conventional commit-meldinger med Nav-relevante scopes og breaking change-format
Expert builder for the Aksel design system (Nav / @navikt) React components, design tokens, layout primitives, theming (light/dark), icons, CSS, the Tailwind preset, version migrations, and Figma-to-code. Trigger on any frontend UI task that mentions Aksel, Nav/Navikt, "designsystemet", or @navikt/ds-* / @navikt/aksel-* packages — or that asks to add, create, build, or refactor a component (button, input, modal, table, alert, card, form) or layout, or to implement a design from Figma (a pasted figma.com/design/...?node-id link, "implement this design", "build this from Figma", design-to-code). Strong signals "using/with aksel", "@navikt/ds-react", "design system", a pasted figma.com link. If the work is frontend UI and there is any Aksel signal, invoke this skill unless the user explicitly opts out.
Integrer og konfigurer Nav Dekoratøren – felles header og footer for nav.no-applikasjoner. Bruk når et team skal ta i bruk Dekoratøren, oppdatere konfigurasjon, legge til breadcrumbs/språkvelger/analytics, håndtere samtykke (ekomloven), CSP eller feilsøke integrasjon mot dekoratøren.
Lag responsive layouts med Aksel Design System (v8+) - spacing tokens, layout primitives (Box, HStack, VStack, HGrid, Page, Bleed) og ResponsiveProp
Generer og kjør Playwright E2E-tester for webapplikasjoner med page objects, auth fixtures og tilgjengelighetstester
Kompakt output-stil som kutter fyllord og beholder teknisk substans — spar output-tokens uten å miste nøyaktighet.
| name | rust-development |
| description | Idiomatisk Rust-utvikling med cargo, clippy, error handling, async/tokio, unsafe og testing |
| license | MIT |
| compatibility | Rust project with Cargo |
| metadata | {"domain":"backend","tags":"rust cargo clippy async tokio"} |
Patterns, templates, and procedures for building high-quality Rust applications and libraries. Based on Microsoft Pragmatic Rust Guidelines and Rust API Guidelines.
Cargo.toml with recommended lints and dependenciesunsafe codecargo init <project-name>
cd <project-name>
[package]
name = "my-service"
version = "0.1.0"
edition = "2024"
rust-version = "1.85"
[dependencies]
anyhow = "1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tokio = { version = "1", features = ["full"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
[dev-dependencies]
proptest = "1"
[lints.rust]
missing_debug_implementations = "warn"
redundant_imports = "warn"
trivial_numeric_casts = "warn"
unsafe_op_in_unsafe_fn = "warn"
unused_lifetimes = "warn"
[lints.clippy]
cargo = { level = "warn", priority = -1 }
complexity = { level = "warn", priority = -1 }
correctness = { level = "warn", priority = -1 }
pedantic = { level = "warn", priority = -1 }
perf = { level = "warn", priority = -1 }
style = { level = "warn", priority = -1 }
suspicious = { level = "warn", priority = -1 }
undocumented_unsafe_blocks = "warn"
clone_on_ref_ptr = "warn"
map_err_ignore = "warn"
Create rustfmt.toml:
edition = "2024"
max_width = 100
use_field_init_shorthand = true
Minimum verification pipeline:
cargo fmt --check
cargo clippy -- -W clippy::pedantic
cargo test
cargo doc --no-deps
cargo audit
Use struct-based errors with backtrace support per Microsoft guidelines:
use std::backtrace::Backtrace;
#[derive(Debug)]
pub struct ParseError {
kind: ParseErrorKind,
backtrace: Backtrace,
}
#[derive(Debug, thiserror::Error)]
enum ParseErrorKind {
#[error("invalid header: {0}")]
InvalidHeader(String),
#[error("missing field: {field}")]
MissingField { field: &'static str },
#[error(transparent)]
Io(#[from] std::io::Error),
}
impl std::fmt::Display for ParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.kind.fmt(f)
}
}
impl std::error::Error for ParseError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.kind.source()
}
}
use anyhow::{Context, Result};
fn load_config(path: &str) -> Result<Config> {
let content = std::fs::read_to_string(path)
.context("failed to read config file")?;
let config: Config = serde_json::from_str(&content)
.context("failed to parse config")?;
Ok(config)
}
Rule: Libraries expose structured errors. Applications use anyhow::Result.
use axum::{Router, routing::get};
use tokio::net::TcpListener;
use tracing_subscriber::EnvFilter;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.json()
.init();
let app = Router::new()
.route("/isalive", get(|| async { "Alive" }))
.route("/isready", get(|| async { "Ready" }));
let listener = TcpListener::bind("0.0.0.0:8080").await?;
tracing::info!("listening on {}", listener.local_addr()?);
axum::serve(listener, app).await?;
Ok(())
}
use tokio::signal;
async fn shutdown_signal() {
let ctrl_c = async {
signal::ctrl_c().await.expect("failed to listen for ctrl+c");
};
#[cfg(unix)]
let terminate = async {
signal::unix::signal(signal::unix::SignalKind::terminate())
.expect("failed to install SIGTERM handler")
.recv()
.await;
};
#[cfg(not(unix))]
let terminate = std::future::pending::<()>();
tokio::select! {
() = ctrl_c => {},
() = terminate => {},
}
}
// Usage:
axum::serve(listener, app)
.with_graceful_shutdown(shutdown_signal())
.await?;
use std::sync::Arc;
use tokio::sync::RwLock;
#[derive(Clone)]
struct AppState {
db: sqlx::PgPool,
cache: Arc<RwLock<HashMap<String, CachedItem>>>,
}
let state = AppState {
db: sqlx::PgPool::connect(&database_url).await?,
cache: Arc::new(RwLock::new(HashMap::new())),
};
let app = Router::new()
.route("/items", get(list_items))
.with_state(state);
When writing or reviewing unsafe:
unsafe block has a // SAFETY: commentunsafe scopecargo +nightly miri test for UB detection// ✅ Correct — documented and minimal
// SAFETY: We verified the pointer is non-null and properly aligned
// in the constructor. The data outlives this reference because
// it is held by the owning Arc<T>.
unsafe { &*self.ptr }
// ❌ Wrong — undocumented, overly broad
unsafe {
// lots of code here making it impossible to audit
}
use mimalloc::MiMalloc;
#[global_allocator]
static GLOBAL: MiMalloc = MiMalloc;
// benches/parse.rs
use criterion::{criterion_group, criterion_main, Criterion};
fn bench_parsing(c: &mut Criterion) {
let input = include_str!("../fixtures/large_input.json");
c.bench_function("parse_json", |b| {
b.iter(|| parse(criterion::black_box(input)));
});
}
criterion_group!(benches, bench_parsing);
criterion_main!(benches);
Enable debug symbols for flamegraphs:
[profile.bench]
debug = 1
// ✅ Pre-allocate with capacity
let mut buffer = Vec::with_capacity(estimated_size);
// ✅ Use write! instead of format! on hot paths
use std::fmt::Write;
let mut output = String::new();
write!(output, "count: {count}")?;
// ✅ Cow for conditional ownership
fn process(input: &str) -> Cow<'_, str> {
if needs_transform(input) {
Cow::Owned(transform(input))
} else {
Cow::Borrowed(input)
}
}
use tracing::{info, warn, instrument};
#[instrument(skip(db), fields(user_id = %user_id))]
async fn process_request(user_id: &str, db: &PgPool) -> Result<()> {
info!(event = "request.processing.started");
let result = db.fetch_one(query).await?;
info!(
event = "request.processing.completed",
rows_affected = result.rows_affected(),
);
Ok(())
}
Naming: <component>.<operation>.<state> — e.g., db.query.completed, http.request.failed.
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parses_valid_input() {
let result = parse("valid input");
assert_eq!(result.unwrap(), expected);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn conversion_cases() {
let cases = [
("input1", "expected1"),
("input2", "expected2"),
("input3", "expected3"),
];
for (input, expected) in cases {
assert_eq!(convert(input), expected, "failed for input: {input}");
}
}
}
#[tokio::test]
async fn fetches_user() {
let pool = setup_test_db().await;
let user = get_user(&pool, "test-id").await.unwrap();
assert_eq!(user.name, "Test User");
}
use proptest::prelude::*;
proptest! {
#[test]
fn roundtrip_serialization(input in "\\PC*") {
let serialized = serde_json::to_string(&input).unwrap();
let deserialized: String = serde_json::from_str(&serialized).unwrap();
prop_assert_eq!(input, deserialized);
}
}
Based on Rust API Guidelines:
Debug, Clone, Default, Eq, Hash where applicable#[non_exhaustive]&str, impl AsRef<Path>) not ownedfn name(&self) not fn get_name(&self)as_ (cheap ref), to_ (expensive), into_ (consuming)new (default), with_* (configured), from_* (conversion)struct UserId(u64))Arc/Box in public signatures unless necessaryIterator, DoubleEndedIterator, ExactSizeIterator where possible/// Short one-sentence summary. (imperative mood)
///
/// Detailed explanation if needed. Include examples for
/// non-trivial public items.
///
/// # Errors
///
/// Returns `ParseError` if the input is not valid UTF-8.
///
/// # Panics
///
/// Panics if `index` is out of bounds.
///
/// # Examples
///
/// ```
/// use my_crate::parse;
/// let result = parse("hello")?;
/// assert_eq!(result.len(), 5);
/// # Ok::<(), my_crate::ParseError>(())
/// ```
pub fn parse(input: &str) -> Result<Parsed, ParseError> {
// ...
}
Required doc sections for public items: summary, # Errors, # Panics, # Examples.
Module docs: //! at the top of lib.rs and significant modules.