use std::{
collections::HashMap,
sync::{Arc, Mutex},
};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use warp::{body, filters::method, path, reply, Filter, Rejection, Reply};
#[derive(Clone, Debug, Default)]
struct Database {
users: Arc<Mutex<HashMap<Uuid, UserInfos>>>,
}
impl Database {
fn new() -> Self {
Self::default()
}
fn post_route(self) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone {
method::post()
.and(body::json::<UserInfosInput>())
.map(move |input| {
let id = Uuid::new_v4();
let user_infos = Self::make_user(id, input);
let response = reply::json(&user_infos);
self.users.lock().unwrap().insert(id, user_infos);
response
})
}
fn get_route(self) -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone {
method::get()
.and(path::param())
.map(move |id| match self.users.lock().unwrap().get(&id) {
Some(user) => reply::json(user),
None => reply::json(&"Failed to get user infos"),
})
}
fn make_user(id: Uuid, input: UserInfosInput) -> UserInfos {
UserInfos {
id,
year_of_birth: input.year_of_birth,
}
}
}
#[derive(Clone, Debug, Serialize, PartialEq)]
struct UserInfos {
id: Uuid,
year_of_birth: usize,
}
#[derive(Clone, Debug, PartialEq, Deserialize)]
struct UserInfosInput {
year_of_birth: usize,
}
#[tokio::main]
async fn main() {
let db = Database::new();
let post = path::path("users").and(db.clone().post_route());
let get = path::path("users").and(db.get_route());
let server = warp::serve(post.or(get)).run(([127, 0, 0, 1], 8080));
server.await
}