Arc<dyn repo>

This commit is contained in:
Jeremy Yin 2023-07-01 18:10:46 +08:00
parent fcc54cc0c9
commit 78ec96f9ae
2 changed files with 28 additions and 13 deletions

View File

@ -1,3 +1,4 @@
use std::sync::Arc;
use crate::domain::entity::{PokemonName, PokemonNumber, PokemonTypes};
use crate::repo::pokemon::{Insert, Repository};
@ -13,7 +14,7 @@ enum Response {
Conflict,
}
fn execute(repo: &mut dyn Repository, req: Request) -> Response {
fn execute(repo: Arc<dyn Repository>, req: Request) -> Response {
println!("execute");
match (
PokemonNumber::try_from(req.number),
@ -23,6 +24,7 @@ fn execute(repo: &mut dyn Repository, req: Request) -> Response {
(Ok(number), Ok(name), Ok(types)) => match repo.insert(number, name, types){
Insert::Ok(num) => Response::Ok(u16::from(num)),
Insert::Conflict => Response::Conflict,
Insert::Error => Response::BadRequest,
},
_ => Response::BadRequest,
}
@ -35,14 +37,14 @@ mod tests {
#[test]
fn it_should_return_the_pokemon_number_otherwise() {
let mut repo = InMemoryRepository::new();
let mut repo = Arc::new(InMemoryRepository::new());
let number = 25;
let req = Request {
number: number,
name: "Pikachu".to_string(),
types: vec!["Electric".to_string(), ],
};
let res = execute(&mut repo, req);
let res = execute(repo, req);
match res {
Response::Ok(num) => assert_eq!(num, number),
_ => unreachable!(),
@ -51,14 +53,14 @@ mod tests {
#[test]
fn it_should_return_a_bad_request_error_when_request_is_invalid() {
let mut repo = InMemoryRepository::new();
let mut repo = Arc::new(InMemoryRepository::new());
let number = 25;
let req = Request {
number: number,
name: "".to_string(),
types: vec!["Electric".to_string(), ],
};
let res = execute(&mut repo, req);
let res = execute(repo, req);
match res {
Response::Ok(num) => assert_eq!(num, number),
Response::BadRequest => {},
@ -71,14 +73,14 @@ mod tests {
let number = PokemonNumber::try_from(25).unwrap();
let name = PokemonName::try_from("Pikachu".to_string()).unwrap();
let types = PokemonTypes::try_from(vec!["Electric".to_string(),]).unwrap();
let mut repo = InMemoryRepository::new();
let mut repo = Arc::new(InMemoryRepository::new());
repo.insert(number, name, types);
let req = Request {
number: 25,
name: "Charmander".to_string(),
types: vec!["File".to_string()],
};
let res = execute(&mut repo, req);
let res = execute(repo, req);
match res {
Response::Conflict => {},
_ => unreachable!(),

View File

@ -1,16 +1,19 @@
use std::sync::Mutex;
use crate::domain::entity::{Pokemon, PokemonName, PokemonNumber, PokemonTypes};
pub trait Repository: Send + Sync {
fn insert(&mut self, number: PokemonNumber, name: PokemonName, types: PokemonTypes) -> Insert;
fn insert(&self, number: PokemonNumber, name: PokemonName, types: PokemonTypes) -> Insert;
}
#[derive(Debug)]
pub struct InMemoryRepository {
pokemons: Vec<Pokemon>
error: bool,
pokemons: Mutex<Vec<Pokemon>>
}
impl InMemoryRepository {
pub fn new() -> Self {
let pokemons: Vec<Pokemon> = vec![];
let pokemons: Mutex<Vec<Pokemon>> = Mutex::new(vec![]);
Self {
error: false,
pokemons
}
}
@ -19,16 +22,26 @@ impl InMemoryRepository {
pub enum Insert {
Ok(PokemonNumber),
Conflict,
Error,
}
impl Repository for InMemoryRepository {
fn insert(&mut self, number: PokemonNumber, name: PokemonName, types: PokemonTypes) -> Insert {
fn insert(&self, number: PokemonNumber, name: PokemonName, types: PokemonTypes) -> Insert {
if self.error {
return Insert::Error;
}
let mut lock = match self.pokemons.lock() {
Ok(lock) => lock,
_ => return Insert::Error,
};
println!("{number:?} {:?}", self.pokemons);
if self.pokemons.iter().any(|pokemon| pokemon.number == number) {
if lock.iter().any(|pokemon| pokemon.number == number) {
return Insert::Conflict;
}
let number_clone = number.clone();
self.pokemons.push(Pokemon::new(number_clone, name, types));
lock.push(Pokemon::new(number_clone, name, types));
println!("{number:?} {:?}", self.pokemons);
Insert::Ok(number)
}