Rust Development
Project Structure
my-project/ ├── Cargo.toml ├── src/ │ ├── main.rs │ ├── lib.rs │ └── handlers/ │ └── mod.rs └── tests/ └── integration.rs
Error Handling
use thiserror::Error;
#[derive(Error, Debug)] pub enum AppError { #[error("User not found: {0}")] NotFound(String),
#[error("Database error: {0}")]
Database(#[from] sqlx::Error),
#[error("Validation error: {0}")]
Validation(String),
}
// Using Result async fn get_user(id: &str) -> Result<User, AppError> { let user = sqlx::query_as!(User, "SELECT * FROM users WHERE id = $1", id) .fetch_optional(&pool) .await? .ok_or_else(|| AppError::NotFound(id.to_string()))?;
Ok(user)
}
// Using ? operator fn process() -> Result<(), AppError> { let user = get_user("123")?; validate(&user)?; save(&user)?; Ok(()) }
Ownership & Borrowing
// Ownership transfer fn take_ownership(s: String) { println!("{}", s); } // s is dropped here
// Borrowing (immutable) fn borrow(s: &String) { println!("{}", s); }
// Mutable borrowing fn mutate(s: &mut String) { s.push_str(" world"); }
// Lifetimes fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } }
Async with Tokio
use tokio;
#[tokio::main] async fn main() { let result = fetch_data().await; }
async fn fetch_all(urls: Vec<String>) -> Vec<Response> { let futures: Vec<_> = urls .into_iter() .map(|url| tokio::spawn(async move { fetch(&url).await })) .collect();
let results = futures::future::join_all(futures).await;
results.into_iter().filter_map(|r| r.ok()).collect()
}
Axum Web Handler
use axum::{ extract::{Path, State}, http::StatusCode, Json, };
async fn get_user( State(pool): State<PgPool>, Path(id): Path<String>, ) -> Result<Json<User>, (StatusCode, String)> { let user = sqlx::query_as!(User, "SELECT * FROM users WHERE id = $1", id) .fetch_optional(&pool) .await .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))? .ok_or((StatusCode::NOT_FOUND, "User not found".to_string()))?;
Ok(Json(user))
}
Testing
#[cfg(test)] mod tests { use super::*;
#[test]
fn test_validation() {
let result = validate("valid@email.com");
assert!(result.is_ok());
}
#[tokio::test]
async fn test_async_operation() {
let result = fetch_data().await;
assert!(result.is_ok());
}
}
Tooling
Format
cargo fmt
Lint
cargo clippy -- -D warnings
Test
cargo test
Build release
cargo build --release