use serde::{Deserialize, Serialize};
use crate::validation::{ProtocolLimits, Validate, ValidationError, check_range};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(try_from = "NeuromodulatorSnapshotWire")]
pub struct NeuromodulatorSnapshot {
pub tick: i64,
pub dopamine: f32,
pub cortisol: f32,
pub acetylcholine: f32,
pub tempo: f32,
}
#[derive(Deserialize)]
pub(super) struct NeuromodulatorSnapshotWire {
pub(super) tick: i64,
pub(super) dopamine: f32,
pub(super) cortisol: f32,
pub(super) acetylcholine: f32,
pub(super) tempo: f32,
}
impl TryFrom<NeuromodulatorSnapshotWire> for NeuromodulatorSnapshot {
type Error = ValidationError;
fn try_from(wire: NeuromodulatorSnapshotWire) -> Result<Self, Self::Error> {
let snapshot = NeuromodulatorSnapshot {
tick: wire.tick,
dopamine: wire.dopamine,
cortisol: wire.cortisol,
acetylcholine: wire.acetylcholine,
tempo: wire.tempo,
};
snapshot.validate()?;
Ok(snapshot)
}
}
impl NeuromodulatorSnapshot {
pub fn from_scores(tick: i64, scores: &[f32; 4]) -> Result<Self, ValidationError> {
let snapshot = Self {
tick,
dopamine: scores[0],
cortisol: scores[1],
acetylcholine: scores[2],
tempo: scores[3],
};
snapshot.validate()?;
Ok(snapshot)
}
}
impl Validate for NeuromodulatorSnapshot {
fn validate_with(&self, _limits: ProtocolLimits) -> Result<(), ValidationError> {
check_range("dopamine", self.dopamine, 0.0, 1.0)?;
check_range("cortisol", self.cortisol, 0.0, 1.0)?;
check_range("acetylcholine", self.acetylcholine, 0.0, 1.0)?;
check_range("tempo", self.tempo, 0.5, 2.0)?;
Ok(())
}
}