PkmnLib_rs/src/static_data/libraries/growth_rate_library.rs

116 lines
4.0 KiB
Rust
Executable File

use std::fmt;
use std::fmt::{Debug, Formatter};
use hashbrown::HashMap;
use crate::defines::LevelInt;
use crate::static_data::GrowthRate;
use crate::{StringKey, ValueIdentifiable, ValueIdentifier};
/// A library to store all growth rates.
pub trait GrowthRateLibrary: Debug + ValueIdentifiable {
/// Calculates the level for a given growth key name and a certain experience.
fn calculate_level(&self, growth_rate: &StringKey, experience: u32) -> LevelInt;
/// Calculates the experience for a given growth key name and a certain level.
fn calculate_experience(&self, growth_rate: &StringKey, level: LevelInt) -> u32;
/// Adds a new growth rate with a name and value.
fn add_growth_rate(&mut self, key: &StringKey, value: Box<dyn GrowthRate>);
}
/// A library to store all growth rates.
pub struct GrowthRateLibraryImpl {
/// A unique identifier so we know what value this is.
identifier: ValueIdentifier,
/// The underlying data structure.
growth_rates: HashMap<StringKey, Box<dyn GrowthRate>>,
}
impl GrowthRateLibraryImpl {
/// Instantiates a new growth rate library with a capacity.
pub fn new(capacity: usize) -> Self {
Self {
identifier: Default::default(),
growth_rates: HashMap::with_capacity(capacity),
}
}
}
impl GrowthRateLibrary for GrowthRateLibraryImpl {
/// Calculates the level for a given growth key name and a certain experience.
fn calculate_level(&self, growth_rate: &StringKey, experience: u32) -> LevelInt {
self.growth_rates[growth_rate].calculate_level(experience)
}
/// Calculates the experience for a given growth key name and a certain level.
fn calculate_experience(&self, growth_rate: &StringKey, level: LevelInt) -> u32 {
self.growth_rates[growth_rate].calculate_experience(level)
}
/// Adds a new growth rate with a name and value.
fn add_growth_rate(&mut self, key: &StringKey, value: Box<dyn GrowthRate>) {
self.growth_rates.insert(key.clone(), value);
}
}
impl ValueIdentifiable for GrowthRateLibraryImpl {
fn value_identifier(&self) -> ValueIdentifier {
self.identifier
}
}
impl Debug for GrowthRateLibraryImpl {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("GrowthRateLibrary").finish()
}
}
#[cfg(test)]
pub mod tests {
use super::*;
use crate::static_data::growth_rates::LookupGrowthRate;
use crate::static_data::libraries::growth_rate_library::GrowthRateLibrary;
use crate::static_data::GrowthRateLibraryImpl;
pub fn build() -> GrowthRateLibraryImpl {
let mut lib = GrowthRateLibraryImpl::new(1);
// Borrow as mut so we can insert
let w = &mut lib;
w.add_growth_rate(
&"test_growthrate".into(),
Box::new(LookupGrowthRate::new(vec![0, 5, 10, 100])),
);
// Drops borrow as mut
lib
}
mockall::mock! {
#[derive(Debug)]
pub GrowthRateLibrary{}
impl GrowthRateLibrary for GrowthRateLibrary {
fn calculate_level(&self, growth_rate: &StringKey, experience: u32) -> LevelInt;
fn calculate_experience(&self, growth_rate: &StringKey, level: LevelInt) -> u32;
fn add_growth_rate(&mut self, key: &StringKey, value: Box<dyn GrowthRate>);
}
impl ValueIdentifiable for GrowthRateLibrary {
fn value_identifier(&self) -> ValueIdentifier{
ValueIdentifier::new(0)
}
}
}
#[test]
fn add_growth_rate_to_library_and_calculate_level() {
let lib = build();
assert_eq!(lib.calculate_level(&"test_growthrate".into(), 3), 1);
assert_eq!(lib.calculate_level(&"test_growthrate".into(), 50), 3);
}
#[test]
fn add_growth_rate_to_library_and_calculate_experience() {
let lib = build();
assert_eq!(lib.calculate_experience(&"test_growthrate".into(), 1), 0);
assert_eq!(lib.calculate_experience(&"test_growthrate".into(), 3), 10);
}
}