use std::time::Duration;
use serde::{Deserialize, Serialize};
use tokio::net::TcpListener;
use tokio::time::sleep;
use taiko::body::JsonError;
use taiko::extract::{ClientIp};
use taiko::prelude::*;
use taiko::request::{Consume, Extract};
use taiko::response::IntoResponse;
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
let listener = TcpListener::bind("0.0.0.0:8080")
.await
.expect("Could not listen to 8080");
let router = Router::new()
.get("/", index);
App::new(())
.handler(router)
.listen(listener)
.await;
}
#[derive(Serialize, Deserialize)]
struct Payload {
message: String
}
#[derive(Serialize, Deserialize)]
enum HttpError {
BadRequest(String)
}
impl IntoResponse for HttpError {
fn into_response(self) -> Response {
match self {
HttpError::BadRequest(message) => Json(Payload {
message: format!("Bad request: {message}")
}).into_response()
}
}
}
impl From<JsonError> for HttpError {
fn from(value: JsonError) -> Self {
HttpError::BadRequest(value.to_string())
}
}
impl From<Empty> for HttpError {
fn from(value: Empty) -> Self {
HttpError::BadRequest("".to_string())
}
}
async fn index(request: Request, _state: ()) -> Result<Json<Payload>, HttpError> {
let ip = ClientIp::extract(&request, &_state).await?;
println!("{ip}");
let Json(payload) = Json::<Payload>::consume(request).await?;
sleep(Duration::from_secs(10)).await;
Ok(Json(Payload {
message: payload.message
}))
}