Skip to main content سوق المهارات اكتشف واستكشف مهارات الذكاء الاصطناعي التي بناها المجتمع.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
نسخ Promptعرض تفاصيل Prompt يتجاوز الأمر المباشر Prompt المخصّص للمراجعة. افحص المصدر قبل تشغيله.
npx skills add https://github.com/personamanagmentlayer/pcl --skill rust-expertيبقى الأمر في سطر واحد. مرّر أفقيًا لمراجعته كاملًا قبل النسخ.
تفضّل نسخة محلية؟ نزّل الملفات المتاحة حاليًا لدى SkillsMP.
تحميل Zip جاري التحميل... المهن ذات الصلة SOC
استنادا إلى تصنيف SOC المهني
name rust-expert version 1.0.0 description Expert-level Rust development with ownership, lifetimes, async, error handling, and production-grade patterns category languages author PCL Team license Apache-2.0 tags ["rust","systems-programming","memory-safety","concurrency","cargo"] allowed-tools ["Read","Write","Edit","Bash(cargo:*, rustc:*, rustup:*)","Glob","Grep"] requirements {"rust":">=1.75"}
Rust Expert
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:
let s1 = String ::from ("hello" );
let s2 = s1;
{
let s = String ::from ("hello" );
}
let mut s = String ::from ("hello" );
let r1 = &s;
let r2 = &s;
let mut s = String ::from ("hello" );
let r1 = &mut s;
Borrowing Patterns:
fn calculate_length (s: &String ) -> usize {
s.len ()
}
fn change (s: &mut String ) {
s.push_str (", world" );
}
let mut s = String ::from ("hello" );
let len = calculate_length (&s);
change (&mut s);
println! ("{}, length: {}" , s, len);
fn first_word <'a >(s: &'a str ) -> &'a str {
let bytes = s.as_bytes ();
for (i, &item) in bytes.iter ().enumerate () {
if item == b' ' {
return &s[0 ..i];
}
}
&s[..]
}
struct ImportantExcerpt <'a > {
part: &'a str ,
}
impl <'a > ImportantExcerpt<'a > {
fn level (&self ) -> i32 {
3
}
fn announce_and_return_part (&self , announcement: &str ) -> &str {
println! ("Attention: {}" , announcement);
self .part
}
}
fn longest <'a , 'b >(x: &'a str , y: &'b str ) -> &'a str
where
'b : 'a ,
{
if x.len () > y.len () { x } else { x }
}
fn first_word (s: &str ) -> &str {
&s[..1 ]
}
let s : &'static str = "I have a static lifetime" ;
Type System Enums and Pattern Matching:
enum Message {
Quit,
Move { x: i32 , y: i32 },
Write (String ),
ChangeColor (i32 , i32 , i32 ),
}
impl Message {
fn call (&self ) {
match self {
Message::Quit => println! ("Quit" ),
Message::Move { x, y } => println! ("Move to {}, {}" , x, y),
Message::Write (text) => println! ("Text: {}" , text),
Message::ChangeColor (r, g, b) => println! ("RGB: {}, {}, {}" , r, g, b),
}
}
}
fn divide (numerator: f64 , denominator: f64 ) -> Option <f64 > {
if denominator == 0.0 {
None
} else {
Some (numerator / denominator)
}
}
match divide (10.0 , 2.0 ) {
Some (result) => println! ("Result: {}" , result),
None => println! ("Cannot divide by zero" ),
}
if let Some (result) = divide (10.0 , 2.0 ) {
println! ("Result: {}" , result);
}
fn read_username_from_file () -> Result <String , std::io::Error> {
let mut file = std::fs::File::open ("username.txt" )?;
let mut username = String ::new ();
file.read_to_string (&mut username)?;
Ok (username)
}
trait Summary {
fn summarize (&self ) -> String ;
fn summarize_author (&self ) -> String {
String ::from ("Unknown" )
}
}
struct Article {
headline: String ,
content: String ,
author: String ,
}
impl Summary for Article {
fn summarize (&self ) -> String {
format! ("{} by {}" , self .headline, self .author)
}
fn summarize_author (&self ) -> String {
self .author.clone ()
}
}
fn notify <T: Summary>(item: &T) {
println! ("Breaking news! {}" , item.summarize ());
}
fn notify_display <T: Summary + std::fmt::Display>(item: &T) {
println! ("{}: {}" , item, item.summarize ());
}
fn some_function <T, U>(t: &T, u: &U) -> i32
where
T: std::fmt::Display + Clone ,
U: Clone + std::fmt::Debug ,
{
42
}
fn returns_summarizable () -> impl Summary {
Article {
headline: String ::from ("News" ),
content: String ::from ("Content here" ),
author: String ::from ("Alice" ),
}
}
struct Point <T> {
x: T,
y: T,
}
impl <T> Point<T> {
fn x (&self ) -> &T {
&self .x
}
}
impl Point <f32 > {
fn distance_from_origin (&self ) -> f32 {
(self .x.powi (2 ) + self .y.powi (2 )).sqrt ()
}
}
enum Option <T> {
Some (T),
None ,
}
enum Result <T, E> {
Ok (T),
Err (E),
}
fn largest <T: PartialOrd >(list: &[T]) -> &T {
let mut largest = &list[0 ];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
Error Handling use std::fs::File;
use std::io::{self , Read};
fn read_username () -> Result <String , io::Error> {
let mut file = File::open ("username.txt" )?;
let mut username = String ::new ();
file.read_to_string (&mut username)?;
Ok (username)
}
fn read_username_short () -> Result <String , io::Error> {
let mut username = String ::new ();
File::open ("username.txt" )?.read_to_string (&mut username)?;
Ok (username)
}
fn read_username_shortest () -> Result <String , io::Error> {
std::fs::read_to_string ("username.txt" )
}
use std::fmt;
#[derive(Debug)]
enum MyError {
Io (io::Error),
Parse (std::num::ParseIntError),
Custom (String ),
}
impl fmt ::Display for MyError {
fn fmt (&self , f: &mut fmt::Formatter) -> fmt::Result {
match self {
MyError::Io (err) => write! (f, "IO error: {}" , err),
MyError::Parse (err) => write! (f, "Parse error: {}" , err),
MyError::Custom (msg) => write! (f, "Error: {}" , msg),
}
}
}
impl std ::error::Error for MyError {}
impl From <io::Error> for MyError {
fn from (err: io::Error) -> Self {
MyError::Io (err)
}
}
impl From <std::num::ParseIntError> for MyError {
fn from (err: std::num::ParseIntError) -> Self {
MyError::Parse (err)
}
}
fn process_file (path: &str ) -> Result <i32 , MyError> {
let content = std::fs::read_to_string (path)?;
let number : i32 = content.trim ().parse ()?;
Ok (number * 2 )
}
use anyhow::{Context, Result };
fn read_config () -> Result <String > {
std::fs::read_to_string ("config.toml" )
.context ("Failed to read config file" )
}
use thiserror::Error;
#[derive(Error, Debug)]
pub enum DataError {
#[error("IO error: {0}" )]
Io (#[from] std::io::Error),
#[error("Invalid data at line {line}" )]
InvalidData { line: usize },
#[error("Missing field: {0}" )]
MissingField (String ),
}
Async Programming use tokio;
async fn fetch_url (url: &str ) -> Result <String , reqwest::Error> {
let response = reqwest::get (url).await ?;
let body = response.text ().await ?;
Ok (body)
}
#[tokio::main]
async fn main () {
match fetch_url ("https://example.com" ).await {
Ok (body) => println! ("Body: {}" , body),
Err (e) => eprintln! ("Error: {}" , e),
}
}
async fn fetch_multiple () -> Result <(), Box <dyn std::error::Error>> {
let (result1, result2, result3) = tokio::join!(
fetch_url ("https://example.com" ),
fetch_url ("https://example.org" ),
fetch_url ("https://example.net" ),
);
println! ("Result 1: {:?}" , result1);
println! ("Result 2: {:?}" , result2);
println! ("Result 3: {:?}" , result3);
Ok (())
}
use tokio::time::{sleep, Duration};
async fn race_example () {
tokio::select! {
_ = sleep (Duration::from_secs (1 )) => {
println! ("Timeout!" );
}
result = fetch_url ("https://example.com" ) => {
println! ("Fetch completed: {:?}" , result);
}
}
}
async fn spawn_tasks () {
let handle1 = tokio::spawn (async {
42
});
let handle2 = tokio::spawn (async {
100
});
let result1 = handle1.await .unwrap ();
let result2 = handle2.await .unwrap ();
println! ("Results: {}, {}" , result1, result2);
}
use tokio::sync::{mpsc, oneshot};
async fn mpsc_example () {
let (tx, mut rx) = mpsc::channel (32 );
for i in 0 ..10 {
let tx = tx.clone ();
tokio::spawn (async move {
tx.send (i).await .unwrap ();
});
}
drop (tx);
while let Some (msg) = rx.recv ().await {
println! ("Received: {}" , msg);
}
}
async fn oneshot_example () {
let (tx, rx) = oneshot::channel ();
tokio::spawn (async move {
tx.send (42 ).unwrap ();
});
let value = rx.await .unwrap ();
println! ("Value: {}" , value);
}
Web Development use axum::{
extract::{Path, Query, State},
http::StatusCode,
response::Json,
routing::{get, post},
Router,
};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use tokio::sync::RwLock;
#[derive(Clone)]
struct AppState {
users: Arc<RwLock<Vec <User>>>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
struct User {
id: u64 ,
name: String ,
email: String ,
}
#[derive(Deserialize)]
struct CreateUser {
name: String ,
email: String ,
}
#[derive(Deserialize)]
struct Pagination {
page: Option <usize >,
per_page: Option <usize >,
}
async fn get_users (
State (state): State<AppState>,
Query (pagination): Query<Pagination>,
) -> Json<Vec <User>> {
let users = state.users.read ().await ;
let page = pagination.page.unwrap_or (0 );
let per_page = pagination.per_page.unwrap_or (10 );
let start = page * per_page;
let end = (start + per_page).min (users.len ());
Json (users[start..end].to_vec ())
}
async fn get_user (
State (state): State<AppState>,
Path (id): Path<u64 >,
) -> Result <Json<User>, StatusCode> {
let users = state.users.read ().await ;
users
.iter ()
.find (|u| u.id == id)
.cloned ()
.map (Json)
.ok_or (StatusCode::NOT_FOUND)
}
async fn create_user (
State (state): State<AppState>,
Json (payload): Json<CreateUser>,
) -> (StatusCode, Json<User>) {
let mut users = state.users.write ().await ;
let id = users.len () as u64 + 1 ;
let user = User {
id,
name: payload.name,
email: payload.email,
};
users.push (user.clone ());
(StatusCode::CREATED, Json (user))
}
#[tokio::main]
async fn main () {
let state = AppState {
users: Arc::new (RwLock::new (vec! [
User {
id: 1 ,
name: "Alice" .to_string (),
email: "alice@example.com" .to_string (),
},
])),
};
let app = Router::new ()
.route ("/users" , get (get_users).post (create_user))
.route ("/users/:id" , get (get_user))
.with_state (state);
let listener = tokio::net::TcpListener::bind ("127.0.0.1:3000" )
.await
.unwrap ();
println! ("Server running on http://127.0.0.1:3000" );
axum::serve (listener, app).await .unwrap ();
}
Testing
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add () {
assert_eq! (add (2 , 2 ), 4 );
}
#[test]
fn test_divide () {
assert_eq! (divide (10.0 , 2.0 ), Some (5.0 ));
assert_eq! (divide (10.0 , 0.0 ), None );
}
#[test]
#[should_panic(expected = "divide by zero" )]
fn test_divide_panic () {
divide_panic (10.0 , 0.0 );
}
#[test]
fn test_result () -> Result <(), String > {
if 2 + 2 == 4 {
Ok (())
} else {
Err (String ::from ("Math is broken" ))
}
}
}
#[cfg(test)]
mod proptests {
use proptest::prelude::*;
proptest! {
#[test]
fn test_reverse_twice (ref s in "\\PC*" ) {
let reversed_once : String = s.chars ().rev ().collect ();
let reversed_twice : String = reversed_once.chars ().rev ().collect ();
assert_eq! (s, &reversed_twice);
}
#[test]
fn test_add_commutative (a in 0 ..1000i32 , b in 0 ..1000i32 ) {
assert_eq! (a + b, b + a);
}
}
}
use my_crate::User;
#[test]
fn test_user_creation () {
let user = User::new ("Alice" , "alice@example.com" );
assert_eq! (user.name, "Alice" );
assert_eq! (user.email, "alice@example.com" );
}
#[tokio::test]
async fn test_async_function () {
let result = fetch_data ().await ;
assert! (result.is_ok ());
}
use criterion::{black_box, criterion_group, criterion_main, Criterion};
fn fibonacci (n: u64 ) -> u64 {
match n {
0 => 1 ,
1 => 1 ,
n => fibonacci (n - 1 ) + fibonacci (n - 2 ),
}
}
fn criterion_benchmark (c: &mut Criterion) {
c.bench_function ("fib 20" , |b| b.iter (|| fibonacci (black_box (20 ))));
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
Best Practices
1. Use Idiomatic Rust
let sum : i32 = vec! [1 , 2 , 3 , 4 , 5 ]
.iter ()
.map (|x| x * 2 )
.filter (|x| x > &5 )
.sum ();
match result {
Ok (value) => println! ("Success: {}" , value),
Err (e) => eprintln! ("Error: {}" , e),
}
fn greet (name: &str ) -> String {
format! ("Hello, {}!" , name)
}
2. Avoid Unnecessary Cloning
fn process (data: &Vec <i32 >) -> Vec <i32 > {
data.clone ()
}
fn process (data: &[i32 ]) -> i32 {
data.iter ().sum ()
}
use std::borrow::Cow;
fn process <'a >(data: &'a str ) -> Cow<'a , str > {
if data.contains ("bad" ) {
Cow::Owned (data.replace ("bad" , "good" ))
} else {
Cow::Borrowed (data)
}
}
3. Use the Type System
struct UserId (u64 );
struct ProductId (u64 );
fn get_user (id: UserId) -> User {
}
struct Locked ;
struct Unlocked ;
struct Door <State> {
state: PhantomData<State>,
}
impl Door <Locked> {
fn unlock (self ) -> Door<Unlocked> {
Door { state: PhantomData }
}
}
impl Door <Unlocked> {
fn lock (self ) -> Door<Locked> {
Door { state: PhantomData }
}
fn open (&self ) {
println! ("Opening door" );
}
}
4. Error Handling
fn parse_config (path: &str ) -> Result <Config, ConfigError> {
}
fn get_element (slice: &[i32 ], index: usize ) -> i32 {
if index >= slice.len () {
panic! ("Index out of bounds" );
}
slice[index]
}
fn find_user (id: u64 ) -> Option <User> {
}
5. Use Cargo Features
[dependencies]
serde = { version = "1.0" , features = ["derive" ] }
tokio = { version = "1" , features = ["full" ] }
[dev-dependencies]
criterion = "0.5"
[profile.release]
opt-level = 3
lto = true
codegen-units = 1
6. Documentation
pub fn divide (numerator: f64 , denominator: f64 ) -> Option <f64 > {
if denominator == 0.0 {
None
} else {
Some (numerator / denominator)
}
}
Common Patterns
Builder Pattern #[derive(Default)]
struct User {
name: String ,
email: String ,
age: Option <u32 >,
}
struct UserBuilder {
user: User,
}
impl UserBuilder {
fn new () -> Self {
Self {
user: User::default (),
}
}
fn name (mut self , name: impl Into <String >) -> Self {
self .user.name = name.into ();
self
}
fn email (mut self , email: impl Into <String >) -> Self {
self .user.email = email.into ();
self
}
fn age (mut self , age: u32 ) -> Self {
self .user.age = Some (age);
self
}
fn build (self ) -> User {
self .user
}
}
let user = UserBuilder::new ()
.name ("Alice" )
.email ("alice@example.com" )
.age (30 )
.build ();
RAII (Resource Acquisition Is Initialization) struct File {
handle: std::fs::File,
}
impl File {
fn new (path: &str ) -> std::io::Result <Self > {
let handle = std::fs::File::open (path)?;
Ok (Self { handle })
}
}
impl Drop for File {
fn drop (&mut self ) {
println! ("Closing file" );
}
}
Anti-Patterns to Avoid
1. Fighting the Borrow Checker
let mut data = vec! [1 , 2 , 3 ];
let first = &mut data[0 ];
let second = &mut data[1 ];
let mut data = vec! [1 , 2 , 3 ];
let (left, right) = data.split_at_mut (1 );
left[0 ] = 10 ;
right[0 ] = 20 ;
2. Unnecessary String Allocations
fn greet (name: String ) -> String {
format! ("Hello, {}" , name)
}
fn greet (name: &str ) -> String {
format! ("Hello, {}" , name)
}
3. Using unwrap() in Production
let value = some_option.unwrap ();
let value = some_option.expect ("Value should exist" );
let value = match some_option {
Some (v) => v,
None => return Err (Error::MissingValue),
};
Development Workflow
cargo new my_project
cargo new --lib my_library
cargo build
cargo run
cargo build --release
cargo test
cargo test --test integration_test
cargo test -- --nocapture
cargo doc --open
cargo clippy
cargo clippy -- -D warnings
cargo fmt
cargo fmt --check
cargo add tokio
cargo update
cargo tree
Approach
Embrace Ownership : Let the compiler guide you to safe code
Use the Type System : Encode invariants in types
Handle Errors : Use Result<T, E>, avoid unwrap() in production
Write Idiomatic Code : Follow Rust conventions and patterns
Test Thoroughly : Unit tests, integration tests, doc tests
Document Well : Public APIs need clear documentation
Optimize Later : Write correct code first, optimize with benchmarks
Use Clippy : Fix all warnings before committing
Always write safe, fast, and idiomatic Rust code that leverages the language's strengths in memory safety and zero-cost abstractions.