this post was submitted on 09 Jan 2025
12 points (83.3% liked)

Rust

6402 readers
11 users here now

Welcome to the Rust community! This is a place to discuss about the Rust programming language.

Wormhole

!performance@programming.dev

Credits

  • The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)

founded 2 years ago
MODERATORS
 

Hello, last time I shared my dirty code of pastebin and people suggested me a lot of things so I have implemented those. now the code is reduced to only 42 lines of code :D

last post: https://lemmy.ca/post/36410861

here is the code:

use axum::{extract::Path, routing::get, routing::post, Router};
use std::fs::{read_to_string, File};
use std::io::prelude::*;
use std::sync::atomic::{AtomicUsize, Ordering};

const MAX_FILE_SIZE: usize = 1024 * 1024 * 10;
static mut FILE_COUNT: AtomicUsize = AtomicUsize::new(0);

async fn handle(Path(id): Path<String>) -> String {
    if let Ok(content) = read_to_string(id) {
        return content;
    }
    return String::from("ERROR: File not found");
}

async fn submit_handle(bytes: String) -> String {
    dbg!(&bytes);
    if bytes.len() > MAX_FILE_SIZE {
        // Don't store the file if it exceeds max size
        return String::from("ERROR: max size exceeded");
    }
    unsafe {
        let path = FILE_COUNT.load(Ordering::Relaxed);
        FILE_COUNT.store(path+1, Ordering::Relaxed);
        let mut output = File::create(path.to_string()).unwrap();
        write!(output, "{}", bytes).unwrap();
        let mut url = String::from("http://localhost:3000/");
        url.push_str(&path.to_string());
        return url;
    }
}

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/", get(|| async { "Paste something in pastebin! use curl -X POST http://localhost:3000/submit -d 'this is some data'" }))
        .route("/{id}", get(handle))
        .route("/submit", post(submit_handle));

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

you are viewing a single comment's thread
view the rest of the comments
[–] beeb@lemm.ee 4 points 1 month ago* (last edited 1 month ago) (7 children)

I will probably post an improved version (if you like) but the main point is that you do not need the atomic to be mut, and so you don't need unsafe. Have a look at https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html#method.fetch_add too

[–] kionite231@lemmy.ca 1 points 1 month ago (3 children)

yeah, you are right, I don't need mut. here is the improved version:

use axum::{extract::Path, routing::get, routing::post, Router};
use std::fs::{read_to_string, File};
use std::io::prelude::*;
use std::sync::atomic::{AtomicUsize, Ordering};

const MAX_FILE_SIZE: usize = 1024 * 1024 * 10;
static FILE_COUNT: AtomicUsize = AtomicUsize::new(0);

async fn handle(Path(id): Path<String>) -> String {
    match read_to_string(id) {
        Ok(content) => content,
        Err(e) => e.to_string(),
    }
}

async fn submit_handle(bytes: String) -> String {
    dbg!(&bytes);
    if bytes.len() > MAX_FILE_SIZE {
        // Don't store the file if it exceeds max size
        return String::from("ERROR: max size exceeded");
    }
    let path = FILE_COUNT.load(Ordering::Relaxed);
    FILE_COUNT.fetch_add(1, Ordering::SeqCst);
    let mut output = File::create(path.to_string()).unwrap();
    write!(output, "{}", bytes).unwrap();
    let mut url = String::from("http://localhost:3000/");
    url.push_str(&path.to_string());
    return url;
}

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/", get(|| async { "Paste something in pastebin! use curl -X POST http://localhost:3000/submit -d 'this is some data'" }))
        .route("/{id}", get(handle))
        .route("/submit", post(submit_handle));

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

[–] beeb@lemm.ee 1 points 1 month ago (2 children)

Fetch add will return the old value before updating it so you don't need the ".load" call above it!

[–] kionite231@lemmy.ca 2 points 1 month ago

Thank you very much!

[–] kionite231@lemmy.ca 1 points 1 month ago

wow, now it reduced to only 41 lines of code, that's nice :D

load more comments (3 replies)