Rocket - In-memory counter using State
-
A single counter in-memory counter (multiple browsers share the counter)
[package]
name = "in-memory-counter"
version = "0.1.0"
edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rocket = "0.5.0"
rocket_dyn_templates = { version = "0.1", features = ["tera"] }
serde = "1.0.201"
#![allow(unused)]
fn main() {
#[macro_use]
extern crate rocket;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
use serde::Deserialize;
use rocket::{fairing::AdHoc, State};
use rocket_dyn_templates::{context, Template};
struct HitCount {
count: AtomicUsize,
}
#[derive(Deserialize)]
struct MyConfig {
title: String,
}
#[get("/")]
fn index(hit_count: &State<HitCount>, config: &State<MyConfig>) -> Template {
//let current_count = hit_count.count.load(Ordering::Relaxed);
let current_count = hit_count.count.fetch_add(1, Ordering::Relaxed);
Template::render(
"index",
context! {
title: &config.title,
count: current_count,
},
)
}
#[catch(404)]
fn not_found() -> Template {
Template::render(
"404",
context! {
// Currently the title is set in the template
//title: "404 Not Found"
},
)
}
#[launch]
fn rocket() -> _ {
rocket::build()
.mount("/", routes![index])
.attach(Template::fairing())
.attach(AdHoc::config::<MyConfig>())
.manage(HitCount {
count: AtomicUsize::new(0),
})
.register("/", catchers![not_found])
}
#[cfg(test)]
mod tests;
}
#![allow(unused)]
fn main() {
use rocket::http::Status;
use rocket::local::blocking::Client;
#[test]
fn hello_world() {
let client = Client::tracked(super::rocket()).unwrap();
let response = client.get("/").dispatch();
assert_eq!(response.status(), Status::Ok);
assert_eq!(
response.headers().get_one("Content-Type").unwrap(),
"text/html; charset=utf-8"
);
let html = response.into_string().unwrap();
assert!(html.contains("<title>Rocket with Tera</title>"));
assert!(html.contains("<h1>Rocket with Tera</h1>"));
}
#[test]
fn page_not_found() {
let client = Client::tracked(super::rocket()).unwrap();
let response = client.get("/other").dispatch();
assert_eq!(response.status(), Status::NotFound);
assert_eq!(
response.headers().get_one("Content-Type").unwrap(),
"text/html; charset=utf-8"
);
let html = response.into_string().unwrap();
//assert_eq!(html, "");
assert!(html.contains("<title>404 Not Found</title>"));
assert!(html.contains("<h1>404 Not Found</h1>"));
assert!(html.contains("<div>Page not found</div>"));
}
}
[default]
title = "Rocket with Tera"
[debug]
[release]
{% set title = "404 Not Found" %}
{% include "incl/header" %}
<div>Page not found</div>
{% include "incl/footer" %}
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">
<title>{{ title }}</title>
</head>
<body>
<h1>{{title}}</h1>
{% include "incl/header" %}
<div>
Welcome to your Rocket project! Counted: {{count}}
</div>
{% include "incl/footer" %}