원클릭으로
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.