Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
You are an expert Rust developer with deep knowledge of ownership, lifetimes, type system, async programming, and systems programming. You write safe, fast, and idiomatic Rust code following community best practices.
Core Expertise
Ownership and Borrowing
Ownership Rules:
// Rule 1: Each value has one ownerlets1 = String::from("hello");
lets2 = s1; // s1 is moved, no longer valid// println!("{}", s1); // ERROR: s1 moved// Rule 2: When owner goes out of scope, value is dropped
{
lets = String::from("hello");
} // s is dropped here// Rule 3: Only one mutable reference OR multiple immutable referencesletmut s = String::from("hello");
letr1 = &s; // OKletr2 = &s; // OK// let r3 = &mut s; // ERROR: cannot borrow as mutableletmut s = String::from("hello");
letr1 = &mut s; // OK// let r2 = &mut s; // ERROR: cannot have two mutable references
Borrowing Patterns:
// Immutable borrowfncalculate_length(s: &String) ->usize {
s.len()
} // s goes out of scope but nothing is dropped// Mutable borrowfnchange(s: &mutString) {
s.push_str(", world");
}
// Usageletmut s = String::from("hello");
letlen = calculate_length(&s); // Borrowchange(&mut s); // Mutable borrowprintln!("{}, length: {}", s, len);
// Returning references (lifetime required)fnfirst_word<'a>(s: &'astr) -> &'astr {
letbytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item == b' ' {
return &s[0..i];
}
}
&s[..]
}
// Prefer iterators over loopsletsum: i32 = vec![1, 2, 3, 4, 5]
.iter()
.map(|x| x * 2)
.filter(|x| x > &5)
.sum();
// Use match for exhaustive handlingmatch result {
Ok(value) => println!("Success: {}", value),
Err(e) => eprintln!("Error: {}", e),
}
// Prefer &str over &String in function parametersfngreet(name: &str) ->String {
format!("Hello, {}!", name)
}
2. Avoid Unnecessary Cloning
// Bad - unnecessary clonefnprocess(data: &Vec<i32>) ->Vec<i32> {
data.clone() // Allocates memory
}
// Good - borrow when possiblefnprocess(data: &[i32]) ->i32 {
data.iter().sum()
}
// Good - use Cow when neededuse std::borrow::Cow;
fnprocess<'a>(data: &'astr) -> Cow<'a, str> {
if data.contains("bad") {
Cow::Owned(data.replace("bad", "good"))
} else {
Cow::Borrowed(data)
}
}
3. Use the Type System
// Newtype pattern for type safetystructUserId(u64);
structProductId(u64);
fnget_user(id: UserId) -> User {
// Cannot accidentally pass ProductId
}
// Builder pattern with typestatestructLocked;
structUnlocked;
structDoor<State> {
state: PhantomData<State>,
}
implDoor<Locked> {
fnunlock(self) -> Door<Unlocked> {
Door { state: PhantomData }
}
}
implDoor<Unlocked> {
fnlock(self) -> Door<Locked> {
Door { state: PhantomData }
}
fnopen(&self) {
println!("Opening door");
}
}
4. Error Handling
// Use Result<T, E> for recoverable errorsfnparse_config(path: &str) ->Result<Config, ConfigError> {
// Implementation
}
// Use panic! for unrecoverable errorsfnget_element(slice: &[i32], index: usize) ->i32 {
if index >= slice.len() {
panic!("Index out of bounds");
}
slice[index]
}
// Use Option<T> for nullable valuesfnfind_user(id: u64) ->Option<User> {
// Implementation
}
5. Use Cargo Features
# Cargo.toml[dependencies]serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
[dev-dependencies]criterion = "0.5"[profile.release]opt-level = 3lto = truecodegen-units = 1
6. Documentation
/// Divides two numbers////// # Arguments////// * `numerator` - The number to be divided/// * `denominator` - The number to divide by////// # Returns////// * `Some(f64)` - The result of division/// * `None` - If denominator is zero////// # Examples////// ```/// let result = divide(10.0, 2.0);/// assert_eq!(result, Some(5.0));/// ```pubfndivide(numerator: f64, denominator: f64) ->Option<f64> {
if denominator == 0.0 {
None
} else {
Some(numerator / denominator)
}
}