Rocket - Single hit-counter using a text file
examples/rocket/single-counter-in-text-file/Cargo.toml
[package] name = "single-counter-in-text-file" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] rocket = "0.5" tempdir = "0.3"
examples/rocket/single-counter-in-text-file/src/main.rs
#[macro_use] extern crate rocket; use std::fs::File; use std::io::Write; #[get("/")] fn index() -> String { let file = match std::env::var("COUNTER_PATH") { Ok(val) => std::path::PathBuf::from(val), Err(_) => { let current_dir = std::env::current_dir().unwrap(); current_dir.join("counter.txt") } }; let counter: u32 = if file.exists() { std::fs::read_to_string(&file) .unwrap() .trim_end() .parse() .unwrap() } else { 0 }; let counter = counter + 1; let mut fh = File::create(file).unwrap(); writeln!(&mut fh, "{}", counter).unwrap(); format!("Counter is {}", counter) } #[launch] fn rocket() -> _ { rocket::build().mount("/", routes![index]) } #[cfg(test)] mod tests;
examples/rocket/single-counter-in-text-file/src/tests.rs
use rocket::http::Status; use rocket::local::blocking::Client; use tempdir::TempDir; #[test] fn test_counte() { let tmp_dir = TempDir::new("counter").unwrap(); std::env::set_var("COUNTER_PATH", tmp_dir.path().join("counter.txt")); let client = Client::tracked(super::rocket()).unwrap(); let response = client.get("/").dispatch(); assert_eq!(response.status(), Status::Ok); assert_eq!(response.into_string(), Some("Counter is 1".into())); let response = client.get("/").dispatch(); assert_eq!(response.status(), Status::Ok); assert_eq!(response.into_string(), Some("Counter is 2".into())); }
- Error handling - unwrap.
- File operations are not atomic.
- We don't handle variable overflow properly.