1. Redis Caching
use deadpool_redis::{Config, Runtime, Pool};
use redis::AsyncCommands;
async fn setup_redis() -> Pool {
let cfg = Config::from_url("redis://localhost:6379");
cfg.create_pool(Some(Runtime::Tokio1)).unwrap()
}
async fn get_cached<T: serde::de::DeserializeOwned + serde::Serialize>(
pool: &Pool,
key: &str,
ttl_secs: u64,
fetch: impl std::future::Future<Output = Result<T, anyhow::Error>>,
) -> Result<T, anyhow::Error> {
let mut conn = pool.get().await?;
// Try cache
let cached: Option<String> = conn.get(key).await?;
if let Some(data) = cached {
return Ok(serde_json::from_str(&data)?);
}
// Fetch & cache
let value = fetch.await?;
let serialized = serde_json::to_string(&value)?;
conn.set_ex(key, &serialized, ttl_secs).await?;
Ok(value)
}
2. CLI Tools with Clap
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(name = "myctl", version, about = "My CLI tool")]
struct Cli {
#[command(subcommand)]
command: Commands,
/// Enable verbose output
#[arg(short, long, global = true)]
verbose: bool,
}
#[derive(Subcommand)]
enum Commands {
/// Initialize a new project
Init {
/// Project name
#[arg(short, long)]
name: String,
/// Template to use
#[arg(short, long, default_value = "default")]
template: String,
},
/// Deploy to production
Deploy {
/// Environment
#[arg(short, long)]
env: String,
/// Skip confirmation
#[arg(long)]
yes: bool,
},
/// Run database migrations
Migrate {
#[command(subcommand)]
action: MigrateAction,
},
}
#[derive(Subcommand)]
enum MigrateAction {
Up,
Down { steps: Option<u32> },
Status,
}
fn main() {
let cli = Cli::parse();
match cli.command {
Commands::Init { name, template } => {
println!("Creating project '{}' with template '{}'", name, template);
}
Commands::Deploy { env, yes } => {
println!("Deploying to {}", env);
}
Commands::Migrate { action } => match action {
MigrateAction::Up => println!("Running migrations"),
MigrateAction::Down { steps } => println!("Rolling back {:?}", steps),
MigrateAction::Status => println!("Migration status"),
},
}
}
3. Declarative Macros
// macro_rules! — pattern-based
macro_rules! hashmap {
($($key:expr => $value:expr),* $(,)?) => {
{
let mut map = std::collections::HashMap::new();
$(map.insert($key, $value);)*
map
}
};
}
let scores = hashmap! {
"Alice" => 95,
"Bob" => 87,
"Charlie" => 92,
};
4. Configuration Management
use config::{Config, Environment, File};
#[derive(Deserialize)]
struct AppConfig {
server: ServerConfig,
database: DatabaseConfig,
redis: RedisConfig,
}
#[derive(Deserialize)]
struct ServerConfig {
host: String,
port: u16,
}
#[derive(Deserialize)]
struct DatabaseConfig {
url: String,
max_connections: u32,
}
fn load_config() -> Result<AppConfig, config::ConfigError> {
let config = Config::builder()
.add_source(File::with_name("config/default"))
.add_source(File::with_name("config/local").required(false))
.add_source(Environment::with_prefix("APP").separator("__"))
.build()?;
config.try_deserialize()
}
// APP__SERVER__PORT=3000 → server.port = 3000
Next article: WebAssembly with Rust.