recipes/api/src/repo/ingredient.rs

128 lines
3.7 KiB
Rust
Raw Normal View History

2022-05-13 19:33:08 +03:00
use crate::domain::ingredient::{fetch_by_key, fetch_list, types};
2022-05-14 00:00:42 +03:00
use crate::domain::misc_types;
2022-05-09 17:52:22 +03:00
2022-05-10 00:56:08 +03:00
#[derive(Default)]
pub struct GetIngredientOpts {
2022-05-14 00:00:42 +03:00
pub lang: Option<misc_types::Lang>,
2022-05-13 19:33:08 +03:00
}
impl From<fetch_by_key::RequestOpts> for GetIngredientOpts {
fn from(app: fetch_by_key::RequestOpts) -> Self {
Self { lang: app.lang }
}
}
#[derive(Default)]
pub struct GetIngredientsOpts {
2022-05-14 00:00:42 +03:00
pub lang: Option<misc_types::Lang>,
2022-05-12 00:16:25 +03:00
pub keys: Option<Vec<String>>,
}
2022-05-13 19:33:08 +03:00
impl From<fetch_list::RequestOpts> for GetIngredientsOpts {
2022-05-12 00:16:25 +03:00
fn from(app: fetch_list::RequestOpts) -> Self {
Self {
lang: app.lang,
keys: app.keys,
}
}
2022-05-10 00:56:08 +03:00
}
2022-05-09 17:52:22 +03:00
pub trait IngredientRepo {
2022-05-13 19:33:08 +03:00
fn get_ingredient_opt(&self, key: String, opts: GetIngredientOpts)
-> Option<types::Ingredient>;
fn get_ingredients(&self, opts: GetIngredientsOpts) -> Vec<types::Ingredient>;
2022-05-09 17:52:22 +03:00
}
2022-05-12 00:01:34 +03:00
pub struct StaticIngredientRepo;
2022-05-09 17:52:22 +03:00
impl IngredientRepo for StaticIngredientRepo {
2022-05-13 19:33:08 +03:00
fn get_ingredient_opt(
&self,
key: String,
opts: GetIngredientOpts,
) -> Option<types::Ingredient> {
db::INGREDIENTS
.iter()
.find(|ing| ing.key == &key)
.map(|ing| types::Ingredient::from((ing, opts.lang.unwrap_or_default())))
}
fn get_ingredients(&self, opts: GetIngredientsOpts) -> Vec<types::Ingredient> {
2022-05-10 00:56:08 +03:00
let langs = [opts.lang.unwrap_or_default()].repeat(db::INGREDIENTS.len());
db::INGREDIENTS
.iter()
.zip(langs)
.map(types::Ingredient::from)
2022-05-12 00:16:25 +03:00
.filter(|ing| opts.keys.is_none() || opts.keys.as_ref().unwrap().contains(&ing.key))
2022-05-10 00:56:08 +03:00
.collect::<Vec<_>>()
2022-05-09 17:52:22 +03:00
}
}
2022-05-10 00:09:47 +03:00
#[cfg(test)]
pub struct InMemoryIngredientRepo {
pub ingredients: Vec<db::data::Ingredient>,
}
#[cfg(test)]
impl InMemoryIngredientRepo {
pub fn new() -> Self {
Self {
ingredients: vec![
db::data::Ingredient {
key: "apple",
translates: db::data::IngredientTranslate {
2022-05-13 19:42:43 +03:00
rus: "Яблоко",
eng: Some("Apple"),
2022-05-10 00:09:47 +03:00
},
},
2022-05-10 00:56:08 +03:00
db::data::Ingredient {
key: "orange",
translates: db::data::IngredientTranslate {
2022-05-13 19:42:43 +03:00
rus: "Апельсин",
eng: None,
2022-05-10 00:56:08 +03:00
},
},
2022-05-10 00:09:47 +03:00
db::data::Ingredient {
key: "salt",
translates: db::data::IngredientTranslate {
2022-05-13 19:42:43 +03:00
rus: "Соль",
eng: Some("Salt"),
2022-05-10 00:09:47 +03:00
},
},
2022-05-10 00:56:08 +03:00
db::data::Ingredient {
key: "sugar",
translates: db::data::IngredientTranslate {
2022-05-13 19:42:43 +03:00
rus: "Сахар",
eng: None,
2022-05-10 00:56:08 +03:00
},
},
2022-05-10 00:09:47 +03:00
],
}
}
}
#[cfg(test)]
impl IngredientRepo for InMemoryIngredientRepo {
2022-05-13 19:33:08 +03:00
fn get_ingredient_opt(
&self,
key: String,
opts: GetIngredientOpts,
) -> Option<types::Ingredient> {
self.ingredients
.iter()
.find(|ing| ing.key == &key)
.map(|ing| types::Ingredient::from((ing, opts.lang.unwrap_or_default())))
}
fn get_ingredients(&self, opts: GetIngredientsOpts) -> Vec<types::Ingredient> {
2022-05-10 00:56:08 +03:00
let langs = [opts.lang.unwrap_or_default()].repeat(self.ingredients.len());
2022-05-10 00:09:47 +03:00
self.ingredients
.iter()
.zip(langs)
.map(types::Ingredient::from)
2022-05-12 00:16:25 +03:00
.filter(|ing| opts.keys.is_none() || opts.keys.as_ref().unwrap().contains(&ing.key))
2022-05-10 00:09:47 +03:00
.collect::<Vec<_>>()
}
}