use crate::enums::Species;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct EntityModelConfig {
personality_enabled: bool,
mental_health_enabled: bool,
time_scale: f32,
proximal_process_frequency_threshold: f64,
proximal_process_complexity_threshold: f64,
}
pub const DEFAULT_PROXIMAL_FREQUENCY_THRESHOLD: f64 = 0.3;
pub const DEFAULT_PROXIMAL_COMPLEXITY_THRESHOLD: f64 = 0.3;
impl EntityModelConfig {
#[must_use]
pub fn new() -> Self {
EntityModelConfig {
personality_enabled: false,
mental_health_enabled: false,
time_scale: 1.0,
proximal_process_frequency_threshold: DEFAULT_PROXIMAL_FREQUENCY_THRESHOLD,
proximal_process_complexity_threshold: DEFAULT_PROXIMAL_COMPLEXITY_THRESHOLD,
}
}
#[must_use]
pub fn human_default() -> Self {
EntityModelConfig {
personality_enabled: true,
mental_health_enabled: true,
time_scale: 1.0,
proximal_process_frequency_threshold: DEFAULT_PROXIMAL_FREQUENCY_THRESHOLD,
proximal_process_complexity_threshold: DEFAULT_PROXIMAL_COMPLEXITY_THRESHOLD,
}
}
#[must_use]
pub fn for_species(species: &Species) -> Self {
match species {
Species::Human => EntityModelConfig::human_default(),
Species::Dog
| Species::Cat
| Species::Dolphin
| Species::Horse
| Species::Elephant
| Species::Chimpanzee
| Species::Crow
| Species::Mouse
| Species::Custom { .. } => EntityModelConfig::animal_simple(),
}
}
#[must_use]
pub fn animal_simple() -> Self {
EntityModelConfig {
personality_enabled: true,
mental_health_enabled: false,
time_scale: 1.0,
proximal_process_frequency_threshold: DEFAULT_PROXIMAL_FREQUENCY_THRESHOLD,
proximal_process_complexity_threshold: DEFAULT_PROXIMAL_COMPLEXITY_THRESHOLD,
}
}
#[must_use]
pub fn animal_complex() -> Self {
EntityModelConfig {
personality_enabled: true,
mental_health_enabled: false,
time_scale: 1.0,
proximal_process_frequency_threshold: DEFAULT_PROXIMAL_FREQUENCY_THRESHOLD,
proximal_process_complexity_threshold: DEFAULT_PROXIMAL_COMPLEXITY_THRESHOLD,
}
}
#[must_use]
pub fn with_personality_enabled(mut self, enabled: bool) -> Self {
self.personality_enabled = enabled;
self
}
#[must_use]
pub fn with_mental_health_enabled(mut self, enabled: bool) -> Self {
self.mental_health_enabled = enabled;
self
}
#[must_use]
pub fn with_time_scale(mut self, scale: f32) -> Self {
self.time_scale = scale.max(0.01); self
}
#[must_use]
pub fn with_proximal_frequency_threshold(mut self, threshold: f64) -> Self {
self.proximal_process_frequency_threshold = threshold.clamp(0.0, 1.0);
self
}
#[must_use]
pub fn with_proximal_complexity_threshold(mut self, threshold: f64) -> Self {
self.proximal_process_complexity_threshold = threshold.clamp(0.0, 1.0);
self
}
#[must_use]
pub fn personality_enabled(&self) -> bool {
self.personality_enabled
}
#[must_use]
pub fn mental_health_enabled(&self) -> bool {
self.mental_health_enabled
}
#[must_use]
pub fn time_scale(&self) -> f32 {
self.time_scale
}
#[must_use]
pub fn proximal_frequency_threshold(&self) -> f64 {
self.proximal_process_frequency_threshold
}
#[must_use]
pub fn proximal_complexity_threshold(&self) -> f64 {
self.proximal_process_complexity_threshold
}
#[must_use]
pub fn check_proximal_process_gate(&self, frequency: f64, complexity: f64) -> bool {
frequency >= self.proximal_process_frequency_threshold
&& complexity >= self.proximal_process_complexity_threshold
}
pub fn set_personality_enabled(&mut self, enabled: bool) {
self.personality_enabled = enabled;
}
pub fn set_mental_health_enabled(&mut self, enabled: bool) {
self.mental_health_enabled = enabled;
}
pub fn set_time_scale(&mut self, scale: f32) {
self.time_scale = scale.max(0.01);
}
pub fn set_proximal_frequency_threshold(&mut self, threshold: f64) {
self.proximal_process_frequency_threshold = threshold.clamp(0.0, 1.0);
}
pub fn set_proximal_complexity_threshold(&mut self, threshold: f64) {
self.proximal_process_complexity_threshold = threshold.clamp(0.0, 1.0);
}
}
impl Default for EntityModelConfig {
fn default() -> Self {
EntityModelConfig::human_default()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_creates_default_config() {
let config = EntityModelConfig::new();
assert!(!config.personality_enabled());
assert!(!config.mental_health_enabled());
}
#[test]
fn human_default_has_personality_and_mental_health() {
let config = EntityModelConfig::human_default();
assert!(config.personality_enabled());
assert!(config.mental_health_enabled());
}
#[test]
fn human_default_has_time_scale_one() {
let config = EntityModelConfig::human_default();
assert!((config.time_scale() - 1.0).abs() < f32::EPSILON);
}
#[test]
fn animal_simple_lacks_mental_health() {
let config = EntityModelConfig::animal_simple();
assert!(!config.mental_health_enabled());
assert!(config.personality_enabled());
}
#[test]
fn animal_complex_lacks_mental_health() {
let config = EntityModelConfig::animal_complex();
assert!(!config.mental_health_enabled());
}
#[test]
fn with_personality_enabled_works() {
let config = EntityModelConfig::new().with_personality_enabled(true);
assert!(config.personality_enabled());
let config2 = EntityModelConfig::human_default().with_personality_enabled(false);
assert!(!config2.personality_enabled());
}
#[test]
fn with_mental_health_enabled_works() {
let config = EntityModelConfig::new().with_mental_health_enabled(true);
assert!(config.mental_health_enabled());
}
#[test]
fn with_time_scale_works() {
let config = EntityModelConfig::new().with_time_scale(6.7);
assert!((config.time_scale() - 6.7).abs() < f32::EPSILON);
}
#[test]
fn time_scale_has_minimum() {
let config = EntityModelConfig::new().with_time_scale(-5.0);
assert!(config.time_scale() >= 0.01);
}
#[test]
fn mutators_work() {
let mut config = EntityModelConfig::new();
config.set_personality_enabled(true);
assert!(config.personality_enabled());
config.set_mental_health_enabled(true);
assert!(config.mental_health_enabled());
config.set_time_scale(2.0);
assert!((config.time_scale() - 2.0).abs() < f32::EPSILON);
}
#[test]
fn default_is_human() {
let config = EntityModelConfig::default();
assert!(config.mental_health_enabled());
}
#[test]
fn clone_and_equality() {
let config1 = EntityModelConfig::human_default();
let config2 = config1.clone();
assert_eq!(config1, config2);
}
#[test]
fn debug_format() {
let config = EntityModelConfig::new();
let debug = format!("{:?}", config);
assert!(debug.contains("EntityModelConfig"));
}
#[test]
fn default_proximal_process_thresholds() {
let config = EntityModelConfig::human_default();
assert!((config.proximal_frequency_threshold() - 0.3).abs() < f64::EPSILON);
assert!((config.proximal_complexity_threshold() - 0.3).abs() < f64::EPSILON);
}
#[test]
fn with_proximal_frequency_threshold() {
let config = EntityModelConfig::new().with_proximal_frequency_threshold(0.5);
assert!((config.proximal_frequency_threshold() - 0.5).abs() < f64::EPSILON);
}
#[test]
fn with_proximal_complexity_threshold() {
let config = EntityModelConfig::new().with_proximal_complexity_threshold(0.6);
assert!((config.proximal_complexity_threshold() - 0.6).abs() < f64::EPSILON);
}
#[test]
fn proximal_thresholds_clamped() {
let config = EntityModelConfig::new()
.with_proximal_frequency_threshold(1.5)
.with_proximal_complexity_threshold(-0.5);
assert!((config.proximal_frequency_threshold() - 1.0).abs() < f64::EPSILON);
assert!((config.proximal_complexity_threshold() - 0.0).abs() < f64::EPSILON);
}
#[test]
fn check_proximal_process_gate_both_pass() {
let config = EntityModelConfig::new()
.with_proximal_frequency_threshold(0.3)
.with_proximal_complexity_threshold(0.3);
assert!(config.check_proximal_process_gate(0.5, 0.5));
assert!(config.check_proximal_process_gate(0.3, 0.3)); }
#[test]
fn check_proximal_process_gate_frequency_fails() {
let config = EntityModelConfig::new()
.with_proximal_frequency_threshold(0.3)
.with_proximal_complexity_threshold(0.3);
assert!(!config.check_proximal_process_gate(0.2, 0.5));
}
#[test]
fn check_proximal_process_gate_complexity_fails() {
let config = EntityModelConfig::new()
.with_proximal_frequency_threshold(0.3)
.with_proximal_complexity_threshold(0.3);
assert!(!config.check_proximal_process_gate(0.5, 0.2));
}
#[test]
fn check_proximal_process_gate_both_fail() {
let config = EntityModelConfig::new()
.with_proximal_frequency_threshold(0.3)
.with_proximal_complexity_threshold(0.3);
assert!(!config.check_proximal_process_gate(0.1, 0.1));
}
#[test]
fn set_proximal_thresholds() {
let mut config = EntityModelConfig::new();
config.set_proximal_frequency_threshold(0.4);
config.set_proximal_complexity_threshold(0.5);
assert!((config.proximal_frequency_threshold() - 0.4).abs() < f64::EPSILON);
assert!((config.proximal_complexity_threshold() - 0.5).abs() < f64::EPSILON);
}
#[test]
fn set_proximal_thresholds_clamped() {
let mut config = EntityModelConfig::new();
config.set_proximal_frequency_threshold(2.0);
config.set_proximal_complexity_threshold(-1.0);
assert!((config.proximal_frequency_threshold() - 1.0).abs() < f64::EPSILON);
assert!((config.proximal_complexity_threshold() - 0.0).abs() < f64::EPSILON);
}
#[test]
fn for_species_human_returns_human_default() {
let config = EntityModelConfig::for_species(&Species::Human);
assert!(config.mental_health_enabled());
}
#[test]
fn for_species_dog_returns_animal_simple() {
let config = EntityModelConfig::for_species(&Species::Dog);
assert!(!config.mental_health_enabled());
}
#[test]
fn for_species_cat_returns_animal_simple() {
let config = EntityModelConfig::for_species(&Species::Cat);
assert!(!config.mental_health_enabled());
}
#[test]
fn for_species_dolphin_returns_animal_simple() {
let config = EntityModelConfig::for_species(&Species::Dolphin);
assert!(!config.mental_health_enabled());
}
#[test]
fn for_species_chimpanzee_returns_animal_simple() {
let config = EntityModelConfig::for_species(&Species::Chimpanzee);
assert!(!config.mental_health_enabled());
}
#[test]
fn for_species_mouse_returns_animal_simple() {
let config = EntityModelConfig::for_species(&Species::Mouse);
assert!(!config.mental_health_enabled());
}
#[test]
fn for_species_custom_returns_animal_simple() {
let custom = Species::custom("Parrot", 60, 5, 0.6);
let config = EntityModelConfig::for_species(&custom);
assert!(!config.mental_health_enabled());
}
}