use std::fmt::Debug; use std::sync::Arc; use indexmap::IndexMap; use crate::static_data::DataLibrary; use crate::static_data::Species; use crate::{StringKey, ValueIdentifiable, ValueIdentifier}; /// A library to store all data for Pokemon species. pub trait SpeciesLibrary: DataLibrary + ValueIdentifiable + Debug {} /// A library to store all data for Pokemon species. #[derive(Debug)] pub struct SpeciesLibraryImpl { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// The underlying map. map: IndexMap>, } impl SpeciesLibraryImpl { /// Instantiates a new Species Library. pub fn new(capacity: usize) -> Self { Self { identifier: Default::default(), map: IndexMap::with_capacity(capacity), } } } impl SpeciesLibrary for SpeciesLibraryImpl {} impl DataLibrary for SpeciesLibraryImpl { fn map(&self) -> &IndexMap> { &self.map } fn get_modify(&mut self) -> &mut IndexMap> { &mut self.map } } impl ValueIdentifiable for SpeciesLibraryImpl { fn value_identifier(&self) -> ValueIdentifier { self.identifier } } #[cfg(test)] pub mod tests { use super::*; use crate::static_data::{FormImpl, LearnableMovesImpl, SpeciesImpl, StaticStatisticSet}; use hashbrown::HashSet; use std::sync::Arc; mockall::mock! { #[derive(Debug)] pub SpeciesLibrary{} impl SpeciesLibrary for SpeciesLibrary {} impl DataLibrary for SpeciesLibrary { fn get<'a, 'b>(&'a self, key: &'b StringKey) -> Option> ; fn get_by_hash<'a>(&'a self, key: u32) -> Option>; fn map(&self) -> &IndexMap>; fn get_modify(&mut self) -> &mut IndexMap>; } impl ValueIdentifiable for SpeciesLibrary { fn value_identifier(&self) -> ValueIdentifier{ ValueIdentifier::new(0) } } } fn build_species() -> Arc { Arc::new(SpeciesImpl::new( 0, &"foo".into(), 0.5, &"test_growthrate".into(), 0, Arc::new(FormImpl::new( &"default".into(), 0.0, 0.0, 0, Vec::new(), StaticStatisticSet::new(10, 10, 10, 10, 10, 10), Vec::new(), Vec::new(), Box::new(LearnableMovesImpl::new()), HashSet::new(), )), HashSet::new(), )) } pub fn build() -> Box { let mut lib = SpeciesLibraryImpl::new(1); let species = build_species(); // Borrow as mut so we can insert let w = &mut lib; w.add(&"foo".into(), species); // Drops borrow as mut Box::new(lib) } #[test] fn add_species_to_library_and_fetch() { let lib = build(); // Borrow as read so we can read let r = &lib; let mon = r.get(&"foo".into()); assert!(mon.is_some()); let mon = mon.unwrap(); assert_eq!(mon.id(), 0_u16); assert_eq!(mon.name(), &"foo".into()); assert_eq!(r.len(), 1); } #[test] fn add_species_to_library_then_remove() { let mut lib = build(); lib.remove(&"foo".into()); // Borrow as read so we can read let r = &lib; let mon = r.get(&"foo".into()); assert!(mon.is_none()); assert_eq!(r.len(), 0); } }