Skip to content

Commit

Permalink
Start Implementing Recipes in API
Browse files Browse the repository at this point in the history
  • Loading branch information
isiko committed Jul 27, 2024
1 parent 8c0da21 commit 7e9bc1e
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 10 deletions.
2 changes: 1 addition & 1 deletion api/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ async fn main() {
.nest("/events", events::router())
.nest("/ingredients", ingredients::router())
.nest("/places", places::router())
.nest("/reciepes", reciepes::router())
.nest("/recipes", reciepes::router())
.nest("/calc", mealcalc::router())
.with_state(ApiState { food_base })
.layer(TraceLayer::new_for_http())
Expand Down
74 changes: 68 additions & 6 deletions api/src/reciepes.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
use axum::{
extract::{Path, State},
http::StatusCode,
response::IntoResponse,
routing::{delete, get, post, put},
Router,
Json, Router,
};
use foodlib::Recipe;
use serde::{Deserialize, Serialize};

use crate::ApiState;

pub fn router() -> Router<crate::ApiState> {
Router::new()
.route("/", get(list_reciepes))
.route("/", put(add_reciepe))
.route("/:recipe_id/", get(calc_reciepe))
.route("/:recipe_id/", get(get_recipe))
.route("/:recipe_id/", post(update_reciepe))
.route("/:recipe_id/", delete(update_reciepe))
.route("/:recipe_id/steps/", get(update_reciepe))
Expand All @@ -18,12 +23,69 @@ pub fn router() -> Router<crate::ApiState> {
.route("/:recipe_id/ingredients/", post(calc_reciepe))
}

async fn list_reciepes() -> impl IntoResponse {
StatusCode::NOT_IMPLEMENTED
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
struct RecipeBody {
id: Option<i32>,
name: String,
comment: Option<String>,
}

async fn add_reciepe() -> impl IntoResponse {
StatusCode::NOT_IMPLEMENTED
fn recipe_to_body(recipe: Recipe) -> RecipeBody {
RecipeBody {
id: Some(recipe.recipe_id),
name: recipe.name,
comment: recipe.comment,
}
}

async fn list_reciepes(State(state): State<ApiState>) -> impl IntoResponse {
match state.food_base.get_recipes().await {
Ok(recipes) => (
StatusCode::OK,
Json(recipes.into_iter().map(recipe_to_body).collect::<Vec<_>>()),
)
.into_response(),
Err(_) => (StatusCode::INTERNAL_SERVER_ERROR).into_response(),
}
}

async fn add_reciepe(
State(state): State<ApiState>,
Json(body): Json<RecipeBody>,
) -> impl IntoResponse {
match state.food_base.add_recipe(&body.name, &body.comment).await {
Ok(recipe) => (StatusCode::OK, Json(recipe_to_body(recipe))).into_response(),
Err(_) => (StatusCode::INTERNAL_SERVER_ERROR).into_response(),
}
}

async fn get_recipe(
State(state): State<ApiState>,
Path(recipe_id): Path<i32>,
) -> impl IntoResponse {
match state.food_base.get_recipe(recipe_id).await {
Ok(recipe) => (StatusCode::OK, Json(recipe_to_body(recipe))).into_response(),
Err(_) => StatusCode::NOT_FOUND.into_response(),
}
}

async fn update_recipe(
State(state): State<ApiState>,
Path(recipe_id): Path<i32>,
Json(body): Json<RecipeBody>,
) -> impl IntoResponse {
match state
.food_base
.update_recipe(&Recipe {
recipe_id,
name: body.name,
comment: body.comment,
})
.await
{
Ok(recipe) => (StatusCode::OK, Json(recipe_to_body(recipe))).into_response(),
Err(_) => StatusCode::NOT_FOUND.into_response(),
}
}

async fn calc_reciepe() -> impl IntoResponse {
Expand Down
14 changes: 11 additions & 3 deletions foodlib/src/recipes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,22 +491,30 @@ impl FoodBase {
Ok(recipe)
}

pub async fn insert_recipe(&self, recipe: &Recipe) -> eyre::Result<Recipe> {
pub async fn add_recipe(
&self,
name: &String,
comment: &Option<String>,
) -> eyre::Result<Recipe> {
let recipe = sqlx::query_as!(
Recipe,
r#"
INSERT INTO recipes (name, comment)
VALUES ($1, $2)
RETURNING *
"#,
recipe.name,
recipe.comment,
name.clone(),
comment.clone(),
)
.fetch_one(&*self.pg_pool)
.await?;
Ok(recipe)
}

pub async fn insert_recipe(&self, recipe: &Recipe) -> eyre::Result<Recipe> {
self.add_recipe(&recipe.name, &recipe.comment).await
}

// TODO: Human race condition, add proper locking / edit notifications
pub async fn update_recipe_entries(
&self,
Expand Down

0 comments on commit 7e9bc1e

Please sign in to comment.