Skip to content

Commit

Permalink
Implement Ingredients (API)
Browse files Browse the repository at this point in the history
  • Loading branch information
isiko committed Jul 24, 2024
1 parent 560d05b commit 1d0dccb
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 25 deletions.
13 changes: 8 additions & 5 deletions api/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ struct EventBody {
budget: Option<i64>,
}

// TODO Add Error Handling
async fn add_event(
State(state): State<ApiState>,
Json(body): Json<EventBody>,
Expand Down Expand Up @@ -88,7 +89,7 @@ async fn update_event(
event_id: event_id.clone(),
event_name: body.name.clone(),
comment: body.comment.clone(),
budget: budget,
budget,
};

if let Ok(result) = state.food_base.update_event(&event).await {
Expand All @@ -105,7 +106,7 @@ struct MealBody {
place: i32,
start: i64,
end: i64,
energy: u32,
energy: BigDecimal,
servings: i32,
comment: Option<String>,
}
Expand All @@ -123,7 +124,7 @@ async fn meal_add(
body.place,
NaiveDateTime::from_timestamp_millis(body.start).unwrap(),
NaiveDateTime::from_timestamp_millis(body.end).unwrap(),
BigDecimal::from(body.energy),
body.energy,
body.servings,
body.comment,
)
Expand All @@ -140,7 +141,7 @@ struct MealSelectorBody {

async fn meal_delete(State(state): State<ApiState>, Path(meal_id): Path<i32>) -> impl IntoResponse {
if let Ok(_) = state.food_base.remove_meal(meal_id).await {
StatusCode::OK
StatusCode::NO_CONTENT
} else {
StatusCode::NOT_FOUND
}
Expand Down Expand Up @@ -202,6 +203,7 @@ struct MealReturn {
servings: i32,
comment: Option<String>,
}
// TODO Add Error Handling
async fn meal_list(State(state): State<ApiState>, Path(event_id): Path<i32>) -> impl IntoResponse {
let query = state.food_base.get_event_meals(event_id).await;
match query {
Expand All @@ -211,7 +213,7 @@ async fn meal_list(State(state): State<ApiState>, Path(event_id): Path<i32>) ->
.map(|meal| {
return MealReturn {
meal_id: meal.meal_id,
event_id: event_id,
event_id,
recipe: IdAndName {
id: meal.recipe_id,
name: meal.name,
Expand Down Expand Up @@ -241,6 +243,7 @@ async fn meal_list(State(state): State<ApiState>, Path(event_id): Path<i32>) ->
}
}

// TODO Add Error Handling
async fn get_meal(State(state): State<ApiState>, Path(meal_id): Path<i32>) -> impl IntoResponse {
let query = state.food_base.get_event_meal(meal_id).await;
match query {
Expand Down
79 changes: 69 additions & 10 deletions api/src/ingredients.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,90 @@
use std::{any::Any, borrow::BorrowMut};

use axum::{
extract::{Path, State},
http::StatusCode,
response::IntoResponse,
routing::{delete, get, post, put},
Router,
Json, Router,
};
use foodlib::Ingredient;
use serde::{Deserialize, Serialize};
use sqlx::types::BigDecimal;
use tracing::Instrument;

use crate::ApiState;

pub fn router() -> Router<crate::ApiState> {
Router::new()
.route("/", get(list))
.route("/", put(add))
.route("/:ingredient_id/", get(show_ingredient))
.route("/:ingredient_id/", delete(delete_ingredient))
.route("/:ingredient_id/", post(show_ingredient))
.route("/:ingredient_id/", post(update_ingredient))
}

#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
struct IngredientDataBody {
name: String,
energy: BigDecimal,
comment: Option<String>,
}

// TODO Add Error Handling
async fn add(
State(state): State<ApiState>,
Json(body): Json<IngredientDataBody>,
) -> impl IntoResponse {
match state
.food_base
.add_ingredient(body.name, body.energy, body.comment)
.await
{
Ok(ingredient) => (StatusCode::OK, Json(ingredient)).into_response(),
Err(_) => (StatusCode::INTERNAL_SERVER_ERROR).into_response(),
}
}

async fn add() -> impl IntoResponse {
StatusCode::NOT_IMPLEMENTED
async fn list(State(state): State<ApiState>) -> impl IntoResponse {
match state.food_base.get_ingredients().await {
Ok(ingredient_list) => (StatusCode::OK, Json(ingredient_list)).into_response(),
Err(_) => (StatusCode::INTERNAL_SERVER_ERROR).into_response(),
}
}

async fn list() -> impl IntoResponse {
StatusCode::NOT_IMPLEMENTED
async fn show_ingredient(
State(state): State<ApiState>,
Path(ingredient_id): Path<i32>,
) -> impl IntoResponse {
match state.food_base.get_ingredient(ingredient_id).await {
Ok(ingredient) => (StatusCode::OK, Json(ingredient)).into_response(),
Err(_) => (StatusCode::INTERNAL_SERVER_ERROR).into_response(),
}
}

async fn show_ingredient() -> impl IntoResponse {
StatusCode::NOT_IMPLEMENTED
async fn delete_ingredient(
State(state): State<ApiState>,
Path(ingredient_id): Path<i32>,
) -> impl IntoResponse {
match state.food_base.delete_ingredient(ingredient_id).await {
Ok(_) => StatusCode::NO_CONTENT,
Err(_) => StatusCode::INTERNAL_SERVER_ERROR,
}
}

async fn delete_ingredient() -> impl IntoResponse {
StatusCode::NOT_IMPLEMENTED
async fn update_ingredient(
State(state): State<ApiState>,
Path(ingredient_id): Path<i32>,
Json(body): Json<IngredientDataBody>,
) -> impl IntoResponse {
let ingredient = Ingredient {
ingredient_id,
name: body.name,
energy: body.energy,
comment: body.comment,
};
match state.food_base.update_ingredient(&ingredient).await {
Ok(ingredient) => (StatusCode::OK, Json(ingredient)).into_response(),
Err(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
}
}
21 changes: 11 additions & 10 deletions foodlib/src/ingredients.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use num::FromPrimitive;
use num::Num;
use sqlx::Error;
use std::borrow::Cow;
use std::fmt::Display;
use std::str::FromStr;
Expand Down Expand Up @@ -206,31 +207,31 @@ impl FoodBase {
name: String,
energy: BigDecimal,
comment: Option<String>,
) -> eyre::Result<i32> {
) -> eyre::Result<Ingredient, Error> {
log::debug!("add_ingredient({:?}, {:?}, {:?})", name, energy, comment);
let ingredient = sqlx::query!(
sqlx::query_as!(
Ingredient,
r#"
INSERT INTO ingredients ( name, energy, comment )
VALUES ( $1, $2, $3 )
RETURNING ingredient_id
RETURNING *
"#,
name,
energy,
comment
)
.fetch_one(&*self.pg_pool)
.await?;

Ok(ingredient.ingredient_id)
.await
}

pub async fn update_ingredient(&self, ingredient: &Ingredient) -> eyre::Result<i32> {
let ingredient = sqlx::query!(
pub async fn update_ingredient(&self, ingredient: &Ingredient) -> eyre::Result<Ingredient> {
let ingredient = sqlx::query_as!(
Ingredient,
r#"
UPDATE ingredients
SET name = $1, energy = $2, comment = $3
WHERE ingredient_id = $4
RETURNING ingredient_id
RETURNING *
"#,
ingredient.name,
ingredient.energy,
Expand All @@ -240,7 +241,7 @@ impl FoodBase {
.fetch_one(&*self.pg_pool)
.await?;

Ok(ingredient.ingredient_id)
Ok(ingredient)
}

pub async fn add_ingredient_source(
Expand Down

0 comments on commit 1d0dccb

Please sign in to comment.