我刚开始学习 Rust

发布: (2026年1月4日 GMT+8 13:18)
3 min read
原文: Dev.to

Source: Dev.to

导入

use axum::{
    Json, Router,
    extract::State,
    http::StatusCode,
    routing::{get, post},
};
use rusqlite::Connection;
use serde::{Deserialize, Serialize};
use std::sync::{Arc, Mutex};
use tokio::task;

// Ref: how to use app state
// https://users.rust-lang.org/t/how-to-pass-app-state-in-axum/104458/3

本地模块

// define local module. the file at app_infra/mod.rs
mod app_infra;

应用状态

#[derive(Debug, Clone)]
struct AppState {
    // Ref: how to make un‑clonable object in external mod implementing Clone traits
    // https://itsallaboutthebit.com/arc-mutex/
    // Arc: shared ownership across threads
    // Mutex: exclusive access to the inner value
    db: Arc>,
}

main 函数

#[tokio::main]
async fn main() {
    // initialize tracing
    tracing_subscriber::fmt::init();

    // create a SQLite connection (implementation in `app_infra`)
    let db = match app_infra::create_db_connection() {
        Ok(conn) => conn,
        Err(err) => panic!("error to connect to db {}", err),
    };
    let cloneable_db = Arc::new(Mutex::new(db));

    let app_state = AppState { db: cloneable_db };

    // build the router
    let app = Router::new()
        .route("/", get(root))               // GET /
        .route("/users", post(create_user))  // POST /users
        .with_state(app_state);

    // run the server on port 3000
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await
        .unwrap();
    axum::serve(listener, app).await.unwrap();
}

处理函数

根处理函数

// Basic handler that responds with a static string
async fn root(State(AppState { db }): State) -> &'static str {
    let outside_int = 213_123i32;

    // Use `spawn_blocking` because SQLite I/O is blocking
    // Ref: https://stackoverflow.com/a/75840352
    // Ref: spawn vs spawn_blocking https://stackoverflow.com/a/74547875
    let res = task::spawn_blocking(move || -> Result, rusqlite::Error> {
        let mut all_item: Vec = Vec::new();

        // Acquire the mutex lock
        let locked_db = db.lock().unwrap();

        // Simple query example
        let mut stmt = locked_db.prepare("SELECT * FROM memo LIMIT 1")?;
        let mut rows = stmt.query([])?;
        match rows.next() {
            Ok(Some(row)) => println!("{:?}", row),
            Ok(None) => (),
            Err(_) => (),
        };

        println!("testing outsider variable {:?}", outside_int);
        all_item.push("Mantab".to_string());

        // Mutex is released when `locked_db` goes out of scope
        Ok(all_item)
    })
    .await
    .unwrap();

    // Handle the result (ignore the value for this example)
    let _ = match res {
        Ok(it) => {
            println!("testing modify variable {:?}", it);
            it
        }
        Err(_) => Vec::::new(),
    };

    "Hello, World!"
}

创建用户处理函数

async fn create_user(
    // Parse the request body as JSON into `CreateUser`
    Json(payload): Json,
) -> (StatusCode, Json) {
    // Application logic (placeholder)
    let user = User {
        id: 1337,
        username: payload.username,
    };

    // Return `201 Created` with the user as JSON
    (StatusCode::CREATED, Json(user))
}

数据结构

// Input for `create_user`
#[derive(Deserialize)]
struct CreateUser {
    username: String,
}

// Output for `create_user`
#[derive(Serialize)]
struct User {
    id: u64,
    username: String,
}
Back to Blog

相关文章

阅读更多 »

RwLock HashMap Arc Mutex 文件

rust pub struct Context { pubcrate tools: HashMap>, pubcrate fifos: tokio::sync::RwLock>>>, // ^ ^ ^ } // 许多 fifo,但只有 | async ref counter | | 但仅 ...

构建 Markdown Scribe

我是一名长期想尝试 Rust 的开发者。这个寒假,我终于下定决心——不再找借口。作为自学者,我跳过了详尽的教程,直接专注于……