This commit is contained in:
Ruidy 2020-12-28 19:18:12 +01:00
parent 7b4d311f48
commit 59d782990c
3 changed files with 51 additions and 1 deletions

View file

@ -1,8 +1,11 @@
// #![deny(missing_docs)]
use actix_web::{middleware, App, HttpServer};
use env_logger::Env;
mod task;
/// main starts the server and listen on address 127.0.0.1:8000
#[actix_web::main]
async fn main() -> std::io::Result<()> {
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();

View file

@ -1,17 +1,29 @@
use crate::task::types::*;
use actix_web::http::StatusCode;
use actix_web::{get, post, web, HttpResponse, Result};
use crate::task::types::*;
/// Registers application routes.
///
/// # Example
///
/// ```
/// let app = App::new().configure(task::init);
/// ```
pub fn init(config: &mut web::ServiceConfig) {
config.service(index);
config.service(get_task);
config.service(add_task);
config.service(close_task);
}
/// List all existing tasks.
#[get("/")]
async fn index(data: web::Data<TaskList>) -> Result<HttpResponse> {
Ok(HttpResponse::Ok().json(&data.tasks))
}
/// Fetches the `Task` specified by `id`
#[get("/{id}")]
async fn get_task(
web::Path(id): web::Path<usize>,
@ -21,6 +33,7 @@ async fn get_task(
Ok(HttpResponse::Ok().json(task))
}
/// Creates and stores a new `Task`
#[post("/")]
async fn add_task(form: web::Form<NewTask>, data: web::Data<TaskList>) -> Result<HttpResponse> {
let id = data.tasks.len();
@ -28,3 +41,22 @@ async fn add_task(form: web::Form<NewTask>, data: web::Data<TaskList>) -> Result
// data.tasks.push(new_task);
Ok(HttpResponse::Ok().json(new_task))
}
/// Closes the given task if open, otherwise return an bad request
#[post("/{id}")]
async fn close_task(
web::Path(id): web::Path<usize>,
data: web::Data<TaskList>,
) -> Result<HttpResponse> {
let task = &data.tasks[id];
if task.is_completed {
Ok(HttpResponse::new(StatusCode::BAD_REQUEST))
} else {
let new_task = Task {
is_completed: true,
id: task.id,
title: task.title.clone(),
};
Ok(HttpResponse::Ok().json(new_task))
}
}

View file

@ -1,13 +1,26 @@
use serde::{Deserialize, Serialize};
/// Task model
#[derive(Serialize, Deserialize)]
pub struct Task {
/// unique task identifier
pub id: usize,
/// short task description
pub title: String,
/// task completion status
pub is_completed: bool,
}
impl Task {
/// Create a new task with given title and id.
///
/// A new task is always not completed.
///
/// # Examples
/// ```
/// use task::types::Task;
/// let task = Task::new(42, "Learn Rust");
/// ```
pub fn new(id: usize, title: String) -> Task {
Task {
id,
@ -17,11 +30,13 @@ impl Task {
}
}
/// Task DTO used to create a new task.
#[derive(Serialize, Deserialize)]
pub struct NewTask {
pub title: String,
}
/// The actual task container.
#[derive(Serialize, Deserialize)]
pub struct TaskList {
pub tasks: Vec<Task>,