From f2d24e89dbd8702e548cae6a9cbc2df9f5aad7f9 Mon Sep 17 00:00:00 2001 From: Dmitriy Pleshevskiy Date: Sat, 18 Mar 2023 17:42:20 +0300 Subject: [PATCH] refac: add fetch one ingredient use case --- .../src/app_core/components/ingredient.rs | 1 + .../ingredient/domain/ingredient.rs | 3 +- .../components/ingredient/use_case.rs | 1 + .../ingredient/use_case/fetch_one.rs | 110 ++++++++++++++++++ .../components/recipe/domain/recipe.rs | 3 +- back_core/src/app_core/port.rs | 2 +- back_core/src/app_core/port/context.rs | 0 back_core/src/app_core/port/repo.rs | 3 + back_core/src/app_core/shared.rs | 4 +- back_core/src/app_core/shared/app.rs | 5 + back_core/src/app_core/shared/app/context.rs | 9 ++ back_core/src/app_core/shared/app/lang.rs | 6 + back_core/src/app_core/shared/domain.rs | 3 - back_core/src/app_core/shared/domain/lang.rs | 11 -- back_core/src/lib.rs | 1 + 15 files changed, 142 insertions(+), 20 deletions(-) create mode 100644 back_core/src/app_core/components/ingredient/use_case.rs create mode 100644 back_core/src/app_core/components/ingredient/use_case/fetch_one.rs create mode 100644 back_core/src/app_core/port/context.rs create mode 100644 back_core/src/app_core/shared/app.rs create mode 100644 back_core/src/app_core/shared/app/context.rs create mode 100644 back_core/src/app_core/shared/app/lang.rs delete mode 100644 back_core/src/app_core/shared/domain/lang.rs diff --git a/back_core/src/app_core/components/ingredient.rs b/back_core/src/app_core/components/ingredient.rs index 559136d..6dd71cb 100644 --- a/back_core/src/app_core/components/ingredient.rs +++ b/back_core/src/app_core/components/ingredient.rs @@ -1,3 +1,4 @@ mod domain; +mod use_case; pub use domain::Ingredient; diff --git a/back_core/src/app_core/components/ingredient/domain/ingredient.rs b/back_core/src/app_core/components/ingredient/domain/ingredient.rs index 380cbd7..ce7c322 100644 --- a/back_core/src/app_core/components/ingredient/domain/ingredient.rs +++ b/back_core/src/app_core/components/ingredient/domain/ingredient.rs @@ -1,9 +1,8 @@ -use crate::app_core::shared::{domain::Lang, lib::EntityId}; +use crate::app_core::shared::lib::EntityId; #[derive(Debug, Clone)] pub struct Ingredient { pub key: EntityId, - pub lang: Lang, pub name: String, } diff --git a/back_core/src/app_core/components/ingredient/use_case.rs b/back_core/src/app_core/components/ingredient/use_case.rs new file mode 100644 index 0000000..f25c548 --- /dev/null +++ b/back_core/src/app_core/components/ingredient/use_case.rs @@ -0,0 +1 @@ +mod fetch_one; diff --git a/back_core/src/app_core/components/ingredient/use_case/fetch_one.rs b/back_core/src/app_core/components/ingredient/use_case/fetch_one.rs new file mode 100644 index 0000000..51a65f4 --- /dev/null +++ b/back_core/src/app_core/components/ingredient/use_case/fetch_one.rs @@ -0,0 +1,110 @@ +use crate::app_core::{ + components::ingredient::Ingredient, + port::repo::{FindOneError, IngredientRepoPort}, + shared::lib::UseCase, +}; + +#[derive(Default, Debug)] +pub struct Request { + pub key: String, +} + +type Response = Ingredient; + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("Ingredient not found")] + NotFound, + + #[error("Unknown error")] + Unknown, +} + +pub trait FetchOneIngredientUseCase: UseCase {} + +#[derive(Provider)] +#[shaku(interface = FetchOneIngredientUseCase)] +pub struct FetchOneIngredient { + #[shaku(provide)] + ingredient_repo: Box, +} + +#[async_trait] +impl UseCase for FetchOneIngredient { + async fn execute(&self, req: Request) -> Result { + self.ingredient_repo + .find_one(&req.key) + .await + .map_err(|e| match e { + FindOneError::Unknown => Error::Unknown, + FindOneError::NotFound => Error::NotFound, + }) + } +} + +impl FetchOneIngredientUseCase for FetchOneIngredient {} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + domain::{Context, Lang}, + repo::ingredient::InMemoryIngredientRepo, + }; + + #[test] + fn should_return_ingredient() { + let repo = InMemoryIngredientRepo::new(); + let res = execute(&repo, &Context::default(), String::from("apple")); + + match res { + Ok(apple) => { + assert_eq!(apple.key, String::from("apple")); + assert_eq!(apple.lang, Lang::Rus); + assert_eq!(apple.name, String::from("Яблоко")); + } + _ => unimplemented!(), + } + } + + #[test] + fn should_return_ingredient_with_choosed_lang() { + let repo = InMemoryIngredientRepo::new(); + let res = execute(&repo, &Context::eng(), String::from("apple")); + + match res { + Ok(apple) => { + assert_eq!(apple.key, String::from("apple")); + assert_eq!(apple.lang, Lang::Eng); + assert_eq!(apple.name, String::from("Apple")); + } + _ => unimplemented!(), + } + } + + #[test] + fn should_return_ingredient_with_fallback_lang() { + let repo = InMemoryIngredientRepo::new(); + let res = execute(&repo, &Context::eng(), String::from("orange")); + + match res { + Ok(orange) => { + assert_eq!(orange.key, String::from("orange")); + assert_eq!(orange.lang, Lang::Rus); + assert_eq!(orange.name, String::from("Апельсин")); + } + _ => unimplemented!(), + } + } + + #[test] + fn should_throw_not_found_error() { + let repo = InMemoryIngredientRepo::new(); + let res = execute(&repo, &Context::default(), String::from("wildberries")); + + match res { + Err(ResponseError::NotFound) => {} + _ => unimplemented!(), + } + } +} diff --git a/back_core/src/app_core/components/recipe/domain/recipe.rs b/back_core/src/app_core/components/recipe/domain/recipe.rs index e2bbab3..364aaa7 100644 --- a/back_core/src/app_core/components/recipe/domain/recipe.rs +++ b/back_core/src/app_core/components/recipe/domain/recipe.rs @@ -1,11 +1,10 @@ -use crate::app_core::shared::{domain::Lang, lib::EntityId}; +use crate::app_core::shared::lib::EntityId; use super::RecipeIngredient; #[derive(Debug, Clone)] pub struct Recipe { pub key: EntityId, - pub lang: Lang, pub name: String, pub instructions: Vec, pub ingredients: Vec, diff --git a/back_core/src/app_core/port.rs b/back_core/src/app_core/port.rs index 3775ac0..c426b23 100644 --- a/back_core/src/app_core/port.rs +++ b/back_core/src/app_core/port.rs @@ -1 +1 @@ -mod repo; +pub mod repo; diff --git a/back_core/src/app_core/port/context.rs b/back_core/src/app_core/port/context.rs new file mode 100644 index 0000000..e69de29 diff --git a/back_core/src/app_core/port/repo.rs b/back_core/src/app_core/port/repo.rs index 6ed43a7..7e0dc0a 100644 --- a/back_core/src/app_core/port/repo.rs +++ b/back_core/src/app_core/port/repo.rs @@ -1,6 +1,9 @@ mod ingredient; mod recipe; +pub use ingredient::IngredientRepoPort; +pub use recipe::RecipeRepoPort; + use crate::app_core::shared::lib::{Entity, EntityId}; use shaku::Interface; diff --git a/back_core/src/app_core/shared.rs b/back_core/src/app_core/shared.rs index 304f14d..0d78413 100644 --- a/back_core/src/app_core/shared.rs +++ b/back_core/src/app_core/shared.rs @@ -1,3 +1,5 @@ -pub mod domain; #[macro_use] pub mod lib; + +pub mod app; +pub mod domain; diff --git a/back_core/src/app_core/shared/app.rs b/back_core/src/app_core/shared/app.rs new file mode 100644 index 0000000..63dd9da --- /dev/null +++ b/back_core/src/app_core/shared/app.rs @@ -0,0 +1,5 @@ +mod context; +mod lang; + +pub use context::Context; +pub use lang::Lang; diff --git a/back_core/src/app_core/shared/app/context.rs b/back_core/src/app_core/shared/app/context.rs new file mode 100644 index 0000000..f4c9cb3 --- /dev/null +++ b/back_core/src/app_core/shared/app/context.rs @@ -0,0 +1,9 @@ +use shaku::Interface; + +use super::lang::Lang; + +pub trait Context: Interface { + fn lang(&self) -> &Lang { + &self.lang + } +} diff --git a/back_core/src/app_core/shared/app/lang.rs b/back_core/src/app_core/shared/app/lang.rs new file mode 100644 index 0000000..970c4f0 --- /dev/null +++ b/back_core/src/app_core/shared/app/lang.rs @@ -0,0 +1,6 @@ +#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] +pub enum Lang { + #[default] + Rus, + Eng, +} diff --git a/back_core/src/app_core/shared/domain.rs b/back_core/src/app_core/shared/domain.rs index 318bf52..e69de29 100644 --- a/back_core/src/app_core/shared/domain.rs +++ b/back_core/src/app_core/shared/domain.rs @@ -1,3 +0,0 @@ -mod lang; - -pub use lang::Lang; diff --git a/back_core/src/app_core/shared/domain/lang.rs b/back_core/src/app_core/shared/domain/lang.rs deleted file mode 100644 index 51eb52b..0000000 --- a/back_core/src/app_core/shared/domain/lang.rs +++ /dev/null @@ -1,11 +0,0 @@ -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum Lang { - Rus, - Eng, -} - -impl Default for Lang { - fn default() -> Self { - Lang::Rus - } -} diff --git a/back_core/src/lib.rs b/back_core/src/lib.rs index ad0557b..e73f00f 100644 --- a/back_core/src/lib.rs +++ b/back_core/src/lib.rs @@ -3,6 +3,7 @@ #[macro_use] extern crate async_trait; +#[macro_use] extern crate shaku; #[cfg(test)] #[macro_use]