recipes/api/src/domain/recipe/types.rs

80 lines
2.3 KiB
Rust

use crate::domain::{ingredient::types::Ingredient, misc_types::Lang};
#[derive(Debug, Clone, Serialize)]
pub struct Recipe {
pub key: String,
pub lang: Lang,
pub name: String,
pub instructions: Vec<String>,
pub ingredients: Vec<RecipeIngredient>,
}
impl From<(&db::data::Recipe, Lang, Vec<Ingredient>)> for Recipe {
fn from((db, lang, ingredients): (&db::data::Recipe, Lang, Vec<Ingredient>)) -> Self {
let tr = &db.translates;
let ctr = match lang {
Lang::Rus => &tr.rus,
Lang::Eng => tr.eng.as_ref().unwrap_or(&tr.rus),
};
Self {
key: db.key.to_string(),
lang: if ctr.name == tr.rus.name {
Lang::Rus
} else {
lang
},
name: ctr.name.to_string(),
instructions: ctr.instructions.iter().copied().map(String::from).collect(),
ingredients: db
.ingredients
.iter()
.filter_map(|sing| {
ingredients
.iter()
.find(|ing| sing.key == ing.key)
.map(|ing| RecipeIngredient {
ingredient: ing.clone(),
measure: sing.measure.into(),
})
})
.collect(),
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct RecipeIngredient {
#[serde(flatten)]
pub ingredient: Ingredient,
#[serde(flatten)]
pub measure: RecipeIngredientMeasure,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(tag = "measure", content = "amount")]
pub enum RecipeIngredientMeasure {
#[serde(rename = "g")]
Gram(u32),
#[serde(rename = "kg")]
KiloGram(u32),
#[serde(rename = "ml")]
MilliLiter(u32),
#[serde(rename = "l")]
Liter(u32),
}
impl From<db::data::RecipeIngredientMeasure> for RecipeIngredientMeasure {
fn from(db: db::data::RecipeIngredientMeasure) -> Self {
use db::data::RecipeIngredientMeasure as DbRIM;
use RecipeIngredientMeasure as RIM;
match db {
DbRIM::Gram(val) => RIM::Gram(val),
DbRIM::KiloGram(val) => RIM::KiloGram(val),
DbRIM::MilliLiter(val) => RIM::MilliLiter(val),
DbRIM::Liter(val) => RIM::Liter(val),
}
}
}