Код IT
← Каталог

Первая программа на Axum — Полный `main.rs` и общая схема

Фрагмент из «Первая программа на Axum»: Полный `main.rs` и общая схема.

Rust main.rs
use axum::{
    extract::{Path, State},
    http::StatusCode,
    routing::{delete, get, post},
    Json, Router,
};
use serde::{Deserialize, Serialize};
use std::sync::{Arc, Mutex};

#[derive(Clone, Serialize)]
struct Note {
    id: u32,
    text: String,
}

#[derive(Deserialize)]
struct NoteCreate {
    text: String,
}

type AppState = Arc<Mutex<(Vec<Note>, u32)>>;

#[tokio::main]
async fn main() {
    let state: AppState = Arc::new(Mutex::new((Vec::new(), 1)));

    let app = Router::new()
        .route("/health", get(health))
        .route("/notes", get(list_notes).post(create_note))
        .route("/notes/:id", delete(delete_note))
        .with_state(state);

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await
        .unwrap();
    println!("http://127.0.0.1:3000");
    axum::serve(listener, app).await.unwrap();
}

async fn health() -> &'static str {
    "ok"
}

async fn list_notes(State(state): State<AppState>) -> Json<Vec<Note>> {
    let guard = state.lock().unwrap();
    Json(guard.0.clone())
}

async fn create_note(
    State(state): State<AppState>,
    Json(body): Json<NoteCreate>,
) -> (StatusCode, Json<Note>) {
    let mut guard = state.lock().unwrap();
    let id = guard.1;
    guard.1 += 1;
    let note = Note {
        id,
        text: body.text,
    };
    guard.0.push(note.clone());
    (StatusCode::CREATED, Json(note))
}

async fn delete_note(
    State(state): State<AppState>,
    Path(id): Path<u32>,
) -> StatusCode {
    let mut guard = state.lock().unwrap();
    let len_before = guard.0.len();
    guard.0.retain(|n| n.id != id);
    if guard.0.len() < len_before {
        StatusCode::NO_CONTENT
    } else {
        StatusCode::NOT_FOUND
    }
}
use axum::{
    extract::{Path, State},
    http::StatusCode,
    routing::{delete, get, post},
    Json, Router,
};
use serde::{Deserialize, Serialize};
use std::sync::{Arc, Mutex};

#[derive(Clone, Serialize)]
struct Note {
    id: u32,
    text: String,
}

#[derive(Deserialize)]
struct NoteCreate {
    text: String,
}

type AppState = Arc<Mutex<(Vec<Note>, u32)>>;

#[tokio::main]
async fn main() {
    let state: AppState = Arc::new(Mutex::new((Vec::new(), 1)));

    let app = Router::new()
        .route("/health", get(health))
        .route("/notes", get(list_notes).post(create_note))
        .route("/notes/:id", delete(delete_note))
        .with_state(state);

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await
        .unwrap();
    println!("http://127.0.0.1:3000");
    axum::serve(listener, app).await.unwrap();
}

async fn health() -> &'static str {
    "ok"
}

async fn list_notes(State(state): State<AppState>) -> Json<Vec<Note>> {
    let guard = state.lock().unwrap();
    Json(guard.0.clone())
}

async fn create_note(
    State(state): State<AppState>,
    Json(body): Json<NoteCreate>,
) -> (StatusCode, Json<Note>) {
    let mut guard = state.lock().unwrap();
    let id = guard.1;
    guard.1 += 1;
    let note = Note {
        id,
        text: body.text,
    };
    guard.0.push(note.clone());
    (StatusCode::CREATED, Json(note))
}

async fn delete_note(
    State(state): State<AppState>,
    Path(id): Path<u32>,
) -> StatusCode {
    let mut guard = state.lock().unwrap();
    let len_before = guard.0.len();
    guard.0.retain(|n| n.id != id);
    if guard.0.len() < len_before {
        StatusCode::NO_CONTENT
    } else {
        StatusCode::NOT_FOUND
    }
}