use rama::Layer;
use rama::http::Response;
use rama::http::layer::trace::TraceLayer;
use rama::http::matcher::HttpMatcher;
use rama::http::service::web::response::{Html, IntoResponse};
use rama::http::service::web::{WebService, extract::Form};
use rama::{http::server::HttpServer, rt::Executor};
use serde::{Deserialize, Serialize};
use std::time::Duration;
use tracing::level_filters::LevelFilter;
use tracing_subscriber::{EnvFilter, fmt, layer::SubscriberExt, util::SubscriberInitExt};
#[derive(Serialize, Deserialize, Debug)]
struct Payload {
name: String,
age: i32,
html: Option<bool>,
}
#[tokio::main]
async fn main() {
tracing_subscriber::registry()
.with(fmt::layer())
.with(
EnvFilter::builder()
.with_default_directive(LevelFilter::DEBUG.into())
.from_env_lossy(),
)
.init();
let graceful = rama::graceful::Shutdown::default();
graceful.spawn_task_fn(async move |guard| {
let exec = Executor::graceful(guard);
HttpServer::auto(exec)
.listen(
"127.0.0.1:62002",
TraceLayer::new_for_http().
layer(
WebService::default()
.get(
"/",
Html(
r##"<html>
<body>
<form action="/form" method="post">
<label for="name">Name:</label><br>
<input type="text" id="name" name="name"><br>
<label for="age">Age:</label><br>
<input type="number" id="age" name="age"><br><br>
<input type="hidden" id="html" name="html" value="true"><br>
<input type="submit" value="Submit">
</form>
</body>
</html>"##,
),
)
.on(HttpMatcher::method_get().or_method_post().and_path("/form"), send_form_data),
),
)
.await
.expect("failed to run service");
});
graceful
.shutdown_with_limit(Duration::from_secs(30))
.await
.expect("graceful shutdown");
}
async fn send_form_data(Form(payload): Form<Payload>) -> Response {
tracing::info!("{:?}", payload.name);
let name = payload.name;
let age = payload.age;
if payload.html.unwrap_or_default() {
Html(format!(
r##"<html>
<body>
<h1>Success</h1>
<p>Thank you for submitting the form {}, {} years old.</p>
</body>
</html>"##,
name, age
))
.into_response()
} else {
format!("{} is {} years old.", name, age).into_response()
}
}