api: add filtering by keys
This commit is contained in:
parent
8c367615a1
commit
e2ae40b685
|
@ -1,13 +1,14 @@
|
||||||
use super::types;
|
use super::types;
|
||||||
use crate::repo::ingredient::{GetIngredientOpts, IngredientRepo};
|
use crate::repo::ingredient::IngredientRepo;
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct RequestOpts {
|
pub struct RequestOpts {
|
||||||
pub lang: Option<types::Lang>,
|
pub lang: Option<types::Lang>,
|
||||||
|
pub keys: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(repo: &impl IngredientRepo, opts: RequestOpts) -> Vec<types::Ingredient> {
|
pub fn execute(repo: &impl IngredientRepo, opts: RequestOpts) -> Vec<types::Ingredient> {
|
||||||
repo.get_ingredients(GetIngredientOpts { lang: opts.lang })
|
repo.get_ingredients(opts.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -66,4 +67,25 @@ mod tests {
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_return_filtered_by_keys() {
|
||||||
|
let repo = crate::repo::ingredient::InMemoryIngredientRepo::new();
|
||||||
|
let res = execute(
|
||||||
|
&repo,
|
||||||
|
RequestOpts {
|
||||||
|
keys: Some(vec![String::from("apple")]),
|
||||||
|
..RequestOpts::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
match res.as_slice() {
|
||||||
|
[apple] => {
|
||||||
|
assert_eq!(apple.key, String::from("apple"));
|
||||||
|
assert_eq!(apple.lang, Lang::Rus);
|
||||||
|
assert_eq!(apple.name, String::from("Яблоко"));
|
||||||
|
}
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,18 @@
|
||||||
use crate::domain::ingredient::types;
|
use crate::domain::ingredient::{fetch_list, types};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct GetIngredientOpts {
|
pub struct GetIngredientOpts {
|
||||||
pub lang: Option<types::Lang>,
|
pub lang: Option<types::Lang>,
|
||||||
|
pub keys: Option<Vec<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<fetch_list::RequestOpts> for GetIngredientOpts {
|
||||||
|
fn from(app: fetch_list::RequestOpts) -> Self {
|
||||||
|
Self {
|
||||||
|
lang: app.lang,
|
||||||
|
keys: app.keys,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait IngredientRepo {
|
pub trait IngredientRepo {
|
||||||
|
@ -17,7 +27,8 @@ impl IngredientRepo for StaticIngredientRepo {
|
||||||
db::INGREDIENTS
|
db::INGREDIENTS
|
||||||
.iter()
|
.iter()
|
||||||
.zip(langs)
|
.zip(langs)
|
||||||
.filter_map(|tup| TryFrom::try_from(tup).ok())
|
.filter_map(|tup| types::Ingredient::try_from(tup).ok())
|
||||||
|
.filter(|ing| opts.keys.is_none() || opts.keys.as_ref().unwrap().contains(&ing.key))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +83,8 @@ impl IngredientRepo for InMemoryIngredientRepo {
|
||||||
self.ingredients
|
self.ingredients
|
||||||
.iter()
|
.iter()
|
||||||
.zip(langs)
|
.zip(langs)
|
||||||
.filter_map(|tup| TryFrom::try_from(tup).ok())
|
.filter_map(|tup| types::Ingredient::try_from(tup).ok())
|
||||||
|
.filter(|ing| opts.keys.is_none() || opts.keys.as_ref().unwrap().contains(&ing.key))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ pub fn start() {
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
struct FetchIngredientsOpts<'a> {
|
struct FetchIngredientsOpts<'a> {
|
||||||
lang: Option<&'a str>,
|
lang: Option<&'a str>,
|
||||||
|
keys: Option<Vec<&'a str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<QueryParams<'a>> for FetchIngredientsOpts<'a> {
|
impl<'a> From<QueryParams<'a>> for FetchIngredientsOpts<'a> {
|
||||||
|
@ -56,6 +57,11 @@ impl<'a> From<QueryParams<'a>> for FetchIngredientsOpts<'a> {
|
||||||
.fold(FetchIngredientsOpts::default(), |mut opts, p| {
|
.fold(FetchIngredientsOpts::default(), |mut opts, p| {
|
||||||
match p {
|
match p {
|
||||||
("lang", val) => opts.lang = Some(val),
|
("lang", val) => opts.lang = Some(val),
|
||||||
|
("key", val) => {
|
||||||
|
let mut keys = opts.keys.unwrap_or_default();
|
||||||
|
keys.push(val);
|
||||||
|
opts.keys = Some(keys)
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,7 +73,10 @@ impl<'a> From<QueryParams<'a>> for FetchIngredientsOpts<'a> {
|
||||||
impl From<FetchIngredientsOpts<'_>> for domain::ingredient::fetch_list::RequestOpts {
|
impl From<FetchIngredientsOpts<'_>> for domain::ingredient::fetch_list::RequestOpts {
|
||||||
fn from(rest: FetchIngredientsOpts) -> Self {
|
fn from(rest: FetchIngredientsOpts) -> Self {
|
||||||
let lang = rest.lang.and_then(|l| Lang::from_str(l).ok());
|
let lang = rest.lang.and_then(|l| Lang::from_str(l).ok());
|
||||||
Self { lang }
|
let keys = rest
|
||||||
|
.keys
|
||||||
|
.map(|keys| keys.into_iter().map(String::from).collect());
|
||||||
|
Self { lang, keys }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue