cosmetic changes

This commit is contained in:
Dmitriy Pleshevskiy 2022-05-15 23:25:11 +03:00
parent b9fdcb96d7
commit d15faa1f65
11 changed files with 212 additions and 299 deletions

View File

@ -1,5 +1,4 @@
use super::types; use crate::domain::{Context, Ingredient};
use crate::domain::misc_types::Context;
use crate::repo::ingredient::IngredientRepo; use crate::repo::ingredient::IngredientRepo;
#[derive(Default, Debug)] #[derive(Default, Debug)]
@ -7,18 +6,15 @@ pub struct RequestOpts {
pub keys: Option<Vec<String>>, pub keys: Option<Vec<String>>,
} }
pub fn execute( pub fn execute(repo: &impl IngredientRepo, ctx: &Context, opts: RequestOpts) -> Vec<Ingredient> {
repo: &impl IngredientRepo,
ctx: &Context,
opts: RequestOpts,
) -> Vec<types::Ingredient> {
repo.get_ingredients(ctx, opts.into()) repo.get_ingredients(ctx, opts.into())
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::{domain::misc_types::Lang, repo::ingredient::InMemoryIngredientRepo}; use crate::domain::Lang;
use crate::repo::ingredient::InMemoryIngredientRepo;
#[test] #[test]
fn should_return_all_ingredients() { fn should_return_all_ingredients() {

View File

@ -6,25 +6,3 @@ pub struct Ingredient {
pub lang: Lang, pub lang: Lang,
pub name: String, pub name: String,
} }
impl From<&db::data::Ingredient> for Ingredient {
fn from(db: &db::data::Ingredient) -> Self {
Self::from((db, Lang::Rus))
}
}
impl From<(&db::data::Ingredient, Lang)> for Ingredient {
fn from((db, lang): (&db::data::Ingredient, Lang)) -> Self {
let tr = &db.translates;
let name = match lang {
Lang::Rus => tr.rus,
Lang::Eng => tr.eng.unwrap_or(tr.rus),
};
Self {
key: db.key.to_string(),
lang: if name == tr.rus { Lang::Rus } else { lang },
name: name.to_string(),
}
}
}

View File

@ -2,4 +2,6 @@ pub mod ingredient;
pub mod misc_types; pub mod misc_types;
pub mod recipe; pub mod recipe;
pub use ingredient::types::Ingredient;
pub use misc_types::{Context, Lang}; pub use misc_types::{Context, Lang};
pub use recipe::types::{Measure, Recipe, RecipeIngredient};

View File

@ -10,7 +10,7 @@ pub fn execute(repo: &impl RecipeRepo, ctx: &Context) -> Vec<types::Recipe> {
mod tests { mod tests {
use super::*; use super::*;
use crate::{ use crate::{
domain::{recipe::types::RecipeIngredientMeasure, Lang}, domain::{Lang, Measure},
repo::recipe::InMemoryRecipeRepo, repo::recipe::InMemoryRecipeRepo,
}; };
@ -36,11 +36,11 @@ mod tests {
match salad.ingredients.as_slice() { match salad.ingredients.as_slice() {
[banana, apple, orange] => { [banana, apple, orange] => {
assert_eq!(banana.ingredient.key, "banana"); assert_eq!(banana.ingredient.key, "banana");
assert_eq!(banana.measure, RecipeIngredientMeasure::Gram(150)); assert_eq!(banana.measure, Measure::Gram(150));
assert_eq!(apple.ingredient.key, "apple"); assert_eq!(apple.ingredient.key, "apple");
assert_eq!(apple.measure, RecipeIngredientMeasure::Gram(150)); assert_eq!(apple.measure, Measure::Gram(150));
assert_eq!(orange.ingredient.key, "orange"); assert_eq!(orange.ingredient.key, "orange");
assert_eq!(orange.measure, RecipeIngredientMeasure::Gram(150)); assert_eq!(orange.measure, Measure::Gram(150));
} }
_ => unreachable!(), _ => unreachable!(),
} }

View File

@ -9,60 +9,17 @@ pub struct Recipe {
pub ingredients: Vec<RecipeIngredient>, pub ingredients: Vec<RecipeIngredient>,
} }
impl TryFrom<(&db::data::Recipe, Lang, Vec<Ingredient>)> for Recipe {
type Error = ();
fn try_from(
(db, lang, ingredients): (&db::data::Recipe, Lang, Vec<Ingredient>),
) -> Result<Self, Self::Error> {
let tr = &db.translates;
let ctr = match lang {
Lang::Rus => &tr.rus,
Lang::Eng => tr.eng.as_ref().unwrap_or(&tr.rus),
};
let ingredients = db
.ingredients
.iter()
.map(|sing| {
ingredients
.iter()
.find(|ing| sing.key == ing.key)
.map(|ing| RecipeIngredient {
ingredient: ing.clone(),
measure: sing.measure.into(),
})
.ok_or(())
})
.collect::<Result<Vec<_>, _>>()?;
let instructions = ctr.instructions.iter().copied().map(String::from).collect();
Ok(Self {
key: db.key.to_string(),
lang: if ctr.name == tr.rus.name {
Lang::Rus
} else {
lang
},
name: ctr.name.to_string(),
instructions,
ingredients,
})
}
}
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct RecipeIngredient { pub struct RecipeIngredient {
#[serde(flatten)] #[serde(flatten)]
pub ingredient: Ingredient, pub ingredient: Ingredient,
#[serde(flatten)] #[serde(flatten)]
pub measure: RecipeIngredientMeasure, pub measure: Measure,
} }
#[derive(Debug, Clone, PartialEq, Eq, Serialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(tag = "measure", content = "amount")] #[serde(tag = "measure", content = "amount")]
pub enum RecipeIngredientMeasure { pub enum Measure {
#[serde(rename = "g")] #[serde(rename = "g")]
Gram(u32), Gram(u32),
#[serde(rename = "kg")] #[serde(rename = "kg")]
@ -72,17 +29,3 @@ pub enum RecipeIngredientMeasure {
#[serde(rename = "l")] #[serde(rename = "l")]
Liter(u32), 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),
}
}
}

View File

@ -1,16 +1,5 @@
use crate::domain::ingredient::{fetch_by_key, fetch_list, types}; use crate::domain::ingredient::fetch_list;
use crate::domain::misc_types::{self, Context}; use crate::domain::{Context, Ingredient, Lang};
#[derive(Default)]
pub struct GetIngredientOpts {
pub lang: Option<misc_types::Lang>,
}
impl From<fetch_by_key::RequestOpts> for GetIngredientOpts {
fn from(app: fetch_by_key::RequestOpts) -> Self {
Self { lang: app.lang }
}
}
#[derive(Default)] #[derive(Default)]
pub struct GetIngredientsOpts { pub struct GetIngredientsOpts {
@ -24,27 +13,27 @@ impl From<fetch_list::RequestOpts> for GetIngredientsOpts {
} }
pub trait IngredientRepo { pub trait IngredientRepo {
fn get_ingredient_opt(&self, ctx: &Context, key: String) -> Option<types::Ingredient>; fn get_ingredient_opt(&self, ctx: &Context, key: String) -> Option<Ingredient>;
fn get_ingredients(&self, ctx: &Context, opts: GetIngredientsOpts) -> Vec<types::Ingredient>; fn get_ingredients(&self, ctx: &Context, opts: GetIngredientsOpts) -> Vec<Ingredient>;
} }
pub struct StaticIngredientRepo; pub struct StaticIngredientRepo;
impl IngredientRepo for StaticIngredientRepo { impl IngredientRepo for StaticIngredientRepo {
fn get_ingredient_opt(&self, ctx: &Context, key: String) -> Option<types::Ingredient> { fn get_ingredient_opt(&self, ctx: &Context, key: String) -> Option<Ingredient> {
db::INGREDIENTS db::data::INGREDIENTS
.iter() .iter()
.find(|ing| ing.key == &key) .find(|ing| ing.key == &key)
.map(|ing| types::Ingredient::from((ing, ctx.lang))) .map(|ing| Ingredient::from((ing, ctx.lang)))
} }
fn get_ingredients(&self, ctx: &Context, opts: GetIngredientsOpts) -> Vec<types::Ingredient> { fn get_ingredients(&self, ctx: &Context, opts: GetIngredientsOpts) -> Vec<Ingredient> {
let langs = [ctx.lang].repeat(db::INGREDIENTS.len()); let langs = [ctx.lang].repeat(db::data::INGREDIENTS.len());
db::INGREDIENTS db::data::INGREDIENTS
.iter() .iter()
.zip(langs) .zip(langs)
.map(types::Ingredient::from) .map(Ingredient::from)
.filter(|ing| opts.keys.is_none() || opts.keys.as_ref().unwrap().contains(&ing.key)) .filter(|ing| opts.keys.is_none() || opts.keys.as_ref().unwrap().contains(&ing.key))
.collect::<Vec<_>>() .collect::<Vec<_>>()
} }
@ -52,7 +41,27 @@ impl IngredientRepo for StaticIngredientRepo {
#[cfg(test)] #[cfg(test)]
pub struct InMemoryIngredientRepo { pub struct InMemoryIngredientRepo {
pub ingredients: Vec<db::data::Ingredient>, pub ingredients: Vec<db::Ingredient>,
}
#[cfg(test)]
impl IngredientRepo for InMemoryIngredientRepo {
fn get_ingredient_opt(&self, ctx: &Context, key: String) -> Option<Ingredient> {
self.ingredients
.iter()
.find(|ing| ing.key == &key)
.map(|ing| Ingredient::from((ing, ctx.lang)))
}
fn get_ingredients(&self, ctx: &Context, opts: GetIngredientsOpts) -> Vec<Ingredient> {
let langs = [ctx.lang].repeat(self.ingredients.len());
self.ingredients
.iter()
.zip(langs)
.map(Ingredient::from)
.filter(|ing| opts.keys.is_none() || opts.keys.as_ref().unwrap().contains(&ing.key))
.collect::<Vec<_>>()
}
} }
#[cfg(test)] #[cfg(test)]
@ -60,37 +69,37 @@ impl InMemoryIngredientRepo {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
ingredients: vec![ ingredients: vec![
db::data::Ingredient { db::Ingredient {
key: "banana", key: "banana",
translates: db::data::IngredientTranslate { translates: db::IngredientTranslate {
rus: "Банан", rus: "Банан",
eng: Some("Banana"), eng: Some("Banana"),
}, },
}, },
db::data::Ingredient { db::Ingredient {
key: "apple", key: "apple",
translates: db::data::IngredientTranslate { translates: db::IngredientTranslate {
rus: "Яблоко", rus: "Яблоко",
eng: Some("Apple"), eng: Some("Apple"),
}, },
}, },
db::data::Ingredient { db::Ingredient {
key: "orange", key: "orange",
translates: db::data::IngredientTranslate { translates: db::IngredientTranslate {
rus: "Апельсин", rus: "Апельсин",
eng: None, eng: None,
}, },
}, },
db::data::Ingredient { db::Ingredient {
key: "salt", key: "salt",
translates: db::data::IngredientTranslate { translates: db::IngredientTranslate {
rus: "Соль", rus: "Соль",
eng: Some("Salt"), eng: Some("Salt"),
}, },
}, },
db::data::Ingredient { db::Ingredient {
key: "sugar", key: "sugar",
translates: db::data::IngredientTranslate { translates: db::IngredientTranslate {
rus: "Сахар", rus: "Сахар",
eng: None, eng: None,
}, },
@ -100,22 +109,18 @@ impl InMemoryIngredientRepo {
} }
} }
#[cfg(test)] impl From<(&db::Ingredient, Lang)> for Ingredient {
impl IngredientRepo for InMemoryIngredientRepo { fn from((db, lang): (&db::Ingredient, Lang)) -> Self {
fn get_ingredient_opt(&self, ctx: &Context, key: String) -> Option<types::Ingredient> { let tr = &db.translates;
self.ingredients let name = match lang {
.iter() Lang::Rus => tr.rus,
.find(|ing| ing.key == &key) Lang::Eng => tr.eng.unwrap_or(tr.rus),
.map(|ing| types::Ingredient::from((ing, ctx.lang))) };
}
fn get_ingredients(&self, ctx: &Context, opts: GetIngredientsOpts) -> Vec<types::Ingredient> { Self {
let langs = [ctx.lang].repeat(self.ingredients.len()); key: db.key.to_string(),
self.ingredients lang: if name == tr.rus { Lang::Rus } else { lang },
.iter() name: name.to_string(),
.zip(langs) }
.map(types::Ingredient::from)
.filter(|ing| opts.keys.is_none() || opts.keys.as_ref().unwrap().contains(&ing.key))
.collect::<Vec<_>>()
} }
} }

View File

@ -1,61 +1,68 @@
use crate::domain::{recipe::types, Context}; use crate::domain::{Context, Ingredient, Lang, Measure, Recipe, RecipeIngredient};
use crate::repo;
use super::ingredient::IngredientRepo;
#[cfg(test)] #[cfg(test)]
use db::data as Db; use crate::repo::ingredient::InMemoryIngredientRepo;
#[cfg(test)] use crate::repo::ingredient::{IngredientRepo, StaticIngredientRepo};
use db::data::RecipeIngredientMeasure as DbRIM;
pub trait RecipeRepo { pub trait RecipeRepo {
fn get_recipes(&self, ctx: &Context) -> Vec<types::Recipe>; fn get_recipes(&self, ctx: &Context) -> Vec<Recipe>;
} }
pub struct StaticRecipeRepo; pub struct StaticRecipeRepo;
impl RecipeRepo for StaticRecipeRepo { impl RecipeRepo for StaticRecipeRepo {
fn get_recipes(&self, ctx: &Context) -> Vec<types::Recipe> { fn get_recipes(&self, ctx: &Context) -> Vec<Recipe> {
let ings_repo = repo::ingredient::StaticIngredientRepo; let ings_repo = StaticIngredientRepo;
let ings = ings_repo.get_ingredients(ctx, Default::default()); let ings = ings_repo.get_ingredients(ctx, Default::default());
let langs = [ctx.lang].repeat(db::RECIPES.len()); db::data::RECIPES
db::RECIPES
.iter() .iter()
.zip(langs) .filter_map(|rec| Recipe::try_from((rec, ctx.lang, ings.clone())).ok())
.filter_map(|(rec, lang)| types::Recipe::try_from((rec, lang, ings.clone())).ok())
.collect() .collect()
} }
} }
#[cfg(test)] #[cfg(test)]
pub struct InMemoryRecipeRepo { pub struct InMemoryRecipeRepo {
pub recipes: Vec<db::data::Recipe>, pub recipes: Vec<db::Recipe>,
}
#[cfg(test)]
impl RecipeRepo for InMemoryRecipeRepo {
fn get_recipes(&self, ctx: &Context) -> Vec<Recipe> {
let ings_repo = InMemoryIngredientRepo::new();
let ings = ings_repo.get_ingredients(ctx, Default::default());
self.recipes
.iter()
.filter_map(|rec| Recipe::try_from((rec, ctx.lang, ings.clone())).ok())
.collect()
}
} }
#[cfg(test)] #[cfg(test)]
impl InMemoryRecipeRepo { impl InMemoryRecipeRepo {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
recipes: vec![Db::Recipe { recipes: vec![db::Recipe {
key: "fruit_salad", key: "fruit_salad",
steps: 0, steps: 0,
ingredients: vec![ ingredients: vec![
Db::RecipeIngredient { db::RecipeIngredient {
key: "banana", key: "banana",
measure: DbRIM::Gram(150), measure: db::Measure::Gram(150),
}, },
Db::RecipeIngredient { db::RecipeIngredient {
key: "apple", key: "apple",
measure: DbRIM::Gram(150), measure: db::Measure::Gram(150),
}, },
Db::RecipeIngredient { db::RecipeIngredient {
key: "orange", key: "orange",
measure: DbRIM::Gram(150), measure: db::Measure::Gram(150),
}, },
], ],
translates: Db::RecipeTranslates { translates: db::RecipeTranslates {
rus: Db::RecipeTranslate { rus: db::RecipeTranslate {
name: "Фруктовый салат", name: "Фруктовый салат",
instructions: vec![ instructions: vec![
"Нарезать бананы кружочками", "Нарезать бананы кружочками",
@ -70,25 +77,25 @@ impl InMemoryRecipeRepo {
} }
pub fn with_no_ingredients_found(mut self) -> Self { pub fn with_no_ingredients_found(mut self) -> Self {
self.recipes.push(Db::Recipe { self.recipes.push(db::Recipe {
key: "no_ingredients_found", key: "no_ingredients_found",
steps: 0, steps: 0,
ingredients: vec![ ingredients: vec![
Db::RecipeIngredient { db::RecipeIngredient {
key: "salt", key: "salt",
measure: DbRIM::Gram(5), measure: db::Measure::Gram(5),
}, },
Db::RecipeIngredient { db::RecipeIngredient {
key: "sugar", key: "sugar",
measure: DbRIM::Gram(4), measure: db::Measure::Gram(4),
}, },
Db::RecipeIngredient { db::RecipeIngredient {
key: "wheat_flour", key: "wheat_flour",
measure: DbRIM::Gram(500), measure: db::Measure::Gram(500),
}, },
], ],
translates: Db::RecipeTranslates { translates: db::RecipeTranslates {
rus: Db::RecipeTranslate { rus: db::RecipeTranslate {
name: "Не найдены ингредиенты", name: "Не найдены ингредиенты",
instructions: vec![], instructions: vec![],
}, },
@ -99,17 +106,56 @@ impl InMemoryRecipeRepo {
} }
} }
#[cfg(test)] impl TryFrom<(&db::Recipe, Lang, Vec<Ingredient>)> for Recipe {
impl RecipeRepo for InMemoryRecipeRepo { type Error = ();
fn get_recipes(&self, ctx: &Context) -> Vec<types::Recipe> {
let ings_repo = repo::ingredient::InMemoryIngredientRepo::new();
let ings = ings_repo.get_ingredients(ctx, Default::default());
let langs = [ctx.lang].repeat(self.recipes.len()); fn try_from(
self.recipes (db, lang, ingredients): (&db::Recipe, Lang, Vec<Ingredient>),
) -> Result<Self, Self::Error> {
let tr = &db.translates;
let ctr = match lang {
Lang::Rus => &tr.rus,
Lang::Eng => tr.eng.as_ref().unwrap_or(&tr.rus),
};
let ingredients = db
.ingredients
.iter() .iter()
.zip(langs) .map(|sing| {
.filter_map(|(rec, lang)| types::Recipe::try_from((rec, lang, ings.clone())).ok()) ingredients
.collect() .iter()
.find(|ing| sing.key == ing.key)
.map(|ing| RecipeIngredient {
ingredient: ing.clone(),
measure: sing.measure.into(),
})
.ok_or(())
})
.collect::<Result<Vec<_>, _>>()?;
let instructions = ctr.instructions.iter().copied().map(String::from).collect();
Ok(Self {
key: db.key.to_string(),
lang: if ctr.name == tr.rus.name {
Lang::Rus
} else {
lang
},
name: ctr.name.to_string(),
instructions,
ingredients,
})
}
}
impl From<db::Measure> for Measure {
fn from(db: db::Measure) -> Self {
match db {
db::Measure::Gram(val) => Measure::Gram(val),
db::Measure::KiloGram(val) => Measure::KiloGram(val),
db::Measure::MilliLiter(val) => Measure::MilliLiter(val),
db::Measure::Liter(val) => Measure::Liter(val),
}
} }
} }

View File

@ -14,7 +14,8 @@ fn main() {
fn gen_data_mod() -> Result<(), std::io::Error> { fn gen_data_mod() -> Result<(), std::io::Error> {
let file = fs::File::create("src/data.rs")?; let file = fs::File::create("src/data.rs")?;
let mut buf = BufWriter::new(file); let mut buf = BufWriter::new(file);
write_structs(&mut buf)?;
writeln!(buf, "use crate::types::*;\n")?;
println!("cargo:rerun-if-changed=data/ingredients/*.toml"); println!("cargo:rerun-if-changed=data/ingredients/*.toml");
write_ingredients(&mut buf)?; write_ingredients(&mut buf)?;
println!("cargo:rerun-if-changed=data/recipes/*.toml"); println!("cargo:rerun-if-changed=data/recipes/*.toml");
@ -22,61 +23,6 @@ fn gen_data_mod() -> Result<(), std::io::Error> {
Ok(()) Ok(())
} }
fn write_structs(file: &mut BufWriter<fs::File>) -> Result<(), std::io::Error> {
let structs = r#"#![allow(dead_code)]
#[derive(Debug)]
pub struct Ingredient {
pub key: &'static str,
pub translates: IngredientTranslate,
}
#[derive(Debug)]
pub struct IngredientTranslate {
pub rus: &'static str,
pub eng: Option<&'static str>,
}
#[derive(Debug)]
pub struct Recipe {
pub key: &'static str,
pub steps: u8,
pub ingredients: Vec<RecipeIngredient>,
pub translates: RecipeTranslates,
}
#[derive(Debug)]
pub struct RecipeIngredient {
pub key: &'static str,
pub measure: RecipeIngredientMeasure,
}
#[derive(Debug, Clone, Copy)]
pub enum RecipeIngredientMeasure {
Gram(u32),
KiloGram(u32),
MilliLiter(u32),
Liter(u32),
}
#[derive(Debug)]
pub struct RecipeTranslates {
pub rus: RecipeTranslate,
pub eng: Option<RecipeTranslate>,
}
#[derive(Debug)]
pub struct RecipeTranslate {
pub name: &'static str,
pub instructions: Vec<&'static str>,
}
"#;
writeln!(file, "{}", structs)?;
Ok(())
}
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
pub struct Main { pub struct Main {
ingredients: Option<Vec<Ingredient>>, ingredients: Option<Vec<Ingredient>>,
@ -127,10 +73,7 @@ impl fmt::Debug for RecipeIngredient {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RecipeIngredient") f.debug_struct("RecipeIngredient")
.field("key", &self.key) .field("key", &self.key)
.field( .field("measure", &format_args!("Measure::{:?}", self.measure))
"measure",
&format_args!("RecipeIngredientMeasure::{:?}", self.measure),
)
.finish() .finish()
} }
} }

View File

@ -1,50 +1,4 @@
#![allow(dead_code)] use crate::types::*;
#[derive(Debug)]
pub struct Ingredient {
pub key: &'static str,
pub translates: IngredientTranslate,
}
#[derive(Debug)]
pub struct IngredientTranslate {
pub rus: &'static str,
pub eng: Option<&'static str>,
}
#[derive(Debug)]
pub struct Recipe {
pub key: &'static str,
pub steps: u8,
pub ingredients: Vec<RecipeIngredient>,
pub translates: RecipeTranslates,
}
#[derive(Debug)]
pub struct RecipeIngredient {
pub key: &'static str,
pub measure: RecipeIngredientMeasure,
}
#[derive(Debug, Clone, Copy)]
pub enum RecipeIngredientMeasure {
Gram(u32),
KiloGram(u32),
MilliLiter(u32),
Liter(u32),
}
#[derive(Debug)]
pub struct RecipeTranslates {
pub rus: RecipeTranslate,
pub eng: Option<RecipeTranslate>,
}
#[derive(Debug)]
pub struct RecipeTranslate {
pub name: &'static str,
pub instructions: Vec<&'static str>,
}
pub const INGREDIENTS: [Ingredient; 11] = [ pub const INGREDIENTS: [Ingredient; 11] = [
Ingredient { Ingredient {
@ -156,27 +110,27 @@ pub static ref RECIPES: [Recipe; 1] = [
ingredients: vec![ ingredients: vec![
RecipeIngredient { RecipeIngredient {
key: "salt", key: "salt",
measure: RecipeIngredientMeasure::Gram(5), measure: Measure::Gram(5),
}, },
RecipeIngredient { RecipeIngredient {
key: "sugar", key: "sugar",
measure: RecipeIngredientMeasure::Gram(4), measure: Measure::Gram(4),
}, },
RecipeIngredient { RecipeIngredient {
key: "wheat_flour", key: "wheat_flour",
measure: RecipeIngredientMeasure::Gram(500), measure: Measure::Gram(500),
}, },
RecipeIngredient { RecipeIngredient {
key: "dry_yeast", key: "dry_yeast",
measure: RecipeIngredientMeasure::Gram(7), measure: Measure::Gram(7),
}, },
RecipeIngredient { RecipeIngredient {
key: "olive_oil", key: "olive_oil",
measure: RecipeIngredientMeasure::MilliLiter(25), measure: Measure::MilliLiter(25),
}, },
RecipeIngredient { RecipeIngredient {
key: "water", key: "water",
measure: RecipeIngredientMeasure::MilliLiter(250), measure: Measure::MilliLiter(250),
}, },
], ],
translates: RecipeTranslates { translates: RecipeTranslates {

View File

@ -1,3 +1,4 @@
pub mod data; pub mod data;
pub mod types;
pub use data::{INGREDIENTS, RECIPES}; pub use types::*;

45
db/src/types.rs Normal file
View File

@ -0,0 +1,45 @@
#[derive(Debug)]
pub struct Ingredient {
pub key: &'static str,
pub translates: IngredientTranslate,
}
#[derive(Debug)]
pub struct IngredientTranslate {
pub rus: &'static str,
pub eng: Option<&'static str>,
}
#[derive(Debug)]
pub struct Recipe {
pub key: &'static str,
pub steps: u8,
pub ingredients: Vec<RecipeIngredient>,
pub translates: RecipeTranslates,
}
#[derive(Debug)]
pub struct RecipeIngredient {
pub key: &'static str,
pub measure: Measure,
}
#[derive(Debug, Clone, Copy)]
pub enum Measure {
Gram(u32),
KiloGram(u32),
MilliLiter(u32),
Liter(u32),
}
#[derive(Debug)]
pub struct RecipeTranslates {
pub rus: RecipeTranslate,
pub eng: Option<RecipeTranslate>,
}
#[derive(Debug)]
pub struct RecipeTranslate {
pub name: &'static str,
pub instructions: Vec<&'static str>,
}