mirror of
https://github.com/zaphar/kitchen.git
synced 2025-07-26 20:19:47 -04:00
164 lines
4.3 KiB
Rust
164 lines
4.3 KiB
Rust
|
// Copyright 2022 Jeremy Wall (Jeremy@marzhilsltudios.com)
|
||
|
//
|
||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
// you may not use this file except in compliance with the License.
|
||
|
// You may obtain a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing, software
|
||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
// See the License for the specific language governing permissions and
|
||
|
// limitations under the License.
|
||
|
#[cfg(feature = "server")]
|
||
|
use axum::{
|
||
|
self,
|
||
|
http::StatusCode,
|
||
|
response::{IntoResponse, Response as AxumResponse},
|
||
|
};
|
||
|
use serde::{Deserialize, Serialize};
|
||
|
|
||
|
use recipes::{IngredientKey, RecipeEntry};
|
||
|
|
||
|
#[derive(Serialize, Deserialize)]
|
||
|
pub enum Response<T> {
|
||
|
Success(T),
|
||
|
Err { status: u16, message: String },
|
||
|
NotFound,
|
||
|
Unauthorized,
|
||
|
}
|
||
|
|
||
|
impl<T> Response<T> {
|
||
|
pub fn error<S: Into<String>>(code: u16, msg: S) -> Self {
|
||
|
Self::Err {
|
||
|
status: code,
|
||
|
message: msg.into(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn success(payload: T) -> Self {
|
||
|
Self::Success(payload)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[cfg(feature = "server")]
|
||
|
impl<T> IntoResponse for Response<T>
|
||
|
where
|
||
|
T: Serialize,
|
||
|
{
|
||
|
fn into_response(self) -> AxumResponse {
|
||
|
match &self {
|
||
|
Self::Success(_) => (StatusCode::OK, axum::Json::from(self)).into_response(),
|
||
|
Self::Err { status, message: _ } => {
|
||
|
let code = match StatusCode::from_u16(*status) {
|
||
|
Ok(c) => c,
|
||
|
Err(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||
|
};
|
||
|
(code, axum::Json::from(self)).into_response()
|
||
|
}
|
||
|
Self::NotFound => (StatusCode::NOT_FOUND, axum::Json::from(self)).into_response(),
|
||
|
Self::Unauthorized => {
|
||
|
(StatusCode::UNAUTHORIZED, axum::Json::from(self)).into_response()
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl<T> From<Result<T, String>> for Response<T> {
|
||
|
fn from(val: Result<T, String>) -> Self {
|
||
|
match val {
|
||
|
Ok(val) => Response::Success(val),
|
||
|
Err(e) => Response::error(500, e),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl<T> From<Result<Option<T>, String>> for Response<T>
|
||
|
where
|
||
|
T: Default,
|
||
|
{
|
||
|
fn from(val: Result<Option<T>, String>) -> Self {
|
||
|
match val {
|
||
|
Ok(Some(val)) => Response::Success(val),
|
||
|
Ok(None) => Response::Success(T::default()),
|
||
|
Err(e) => Response::error(500, e),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Serialize, Deserialize)]
|
||
|
pub struct UserData {
|
||
|
pub user_id: String,
|
||
|
}
|
||
|
|
||
|
pub type AccountResponse = Response<UserData>;
|
||
|
|
||
|
impl From<UserData> for AccountResponse {
|
||
|
fn from(user_data: UserData) -> Self {
|
||
|
Response::Success(user_data)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub type RecipeEntryResponse = Response<Vec<RecipeEntry>>;
|
||
|
|
||
|
impl From<Vec<RecipeEntry>> for RecipeEntryResponse {
|
||
|
fn from(entries: Vec<RecipeEntry>) -> Self {
|
||
|
Response::Success(entries)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub type PlanDataResponse = Response<Vec<(String, i32)>>;
|
||
|
|
||
|
impl From<Vec<(String, i32)>> for PlanDataResponse {
|
||
|
fn from(plan: Vec<(String, i32)>) -> Self {
|
||
|
Response::Success(plan)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl From<Option<Vec<(String, i32)>>> for PlanDataResponse {
|
||
|
fn from(plan: Option<Vec<(String, i32)>>) -> Self {
|
||
|
match plan {
|
||
|
Some(plan) => Response::Success(plan),
|
||
|
None => Response::Success(Vec::new()),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Serialize, Deserialize)]
|
||
|
pub struct InventoryData {
|
||
|
pub filtered_ingredients: Vec<IngredientKey>,
|
||
|
pub modified_amts: Vec<(IngredientKey, String)>,
|
||
|
pub extra_items: Vec<(String, String)>,
|
||
|
}
|
||
|
|
||
|
pub type InventoryResponse = Response<InventoryData>;
|
||
|
|
||
|
impl
|
||
|
From<(
|
||
|
Vec<IngredientKey>,
|
||
|
Vec<(IngredientKey, String)>,
|
||
|
Vec<(String, String)>,
|
||
|
)> for InventoryData
|
||
|
{
|
||
|
fn from(
|
||
|
(filtered_ingredients, modified_amts, extra_items): (
|
||
|
Vec<IngredientKey>,
|
||
|
Vec<(IngredientKey, String)>,
|
||
|
Vec<(String, String)>,
|
||
|
),
|
||
|
) -> Self {
|
||
|
InventoryData {
|
||
|
filtered_ingredients,
|
||
|
modified_amts,
|
||
|
extra_items,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl From<InventoryData> for InventoryResponse {
|
||
|
fn from(inventory_data: InventoryData) -> Self {
|
||
|
Response::Success(inventory_data)
|
||
|
}
|
||
|
}
|