#![cfg(feature = "serde")]
use axon_encoder::prelude::*;
#[test]
fn test_serde_core_io() {
let spike = SpikeEvent {
channel: 12,
timestamp: 42,
polarity: true,
};
let serialized_spike = serde_json::to_string(&spike).unwrap();
let deserialized_spike: SpikeEvent = serde_json::from_str(&serialized_spike).unwrap();
assert_eq!(spike, deserialized_spike);
let config = EncoderConfig {
input_channels: 10,
output_channels: 20,
};
let serialized_config = serde_json::to_string(&config).unwrap();
let deserialized_config: EncoderConfig = serde_json::from_str(&serialized_config).unwrap();
assert_eq!(config, deserialized_config);
let mut output = EncodedOutput::new();
output.spikes.push(spike);
output.embeddings = Some(vec![1.0, 2.0, 3.0]);
output.metadata = Some(EncodingMetadata::default());
let serialized_output = serde_json::to_string(&output).unwrap();
let deserialized_output: EncodedOutput = serde_json::from_str(&serialized_output).unwrap();
assert_eq!(output, deserialized_output);
}
#[test]
fn test_serde_encoders_and_state() {
let embed_config = EmbeddingEncoderConfig { v_th: 1.5 };
let serialized_embed_config = serde_json::to_string(&embed_config).unwrap();
let deserialized_embed_config: EmbeddingEncoderConfig =
serde_json::from_str(&serialized_embed_config).unwrap();
assert_eq!(embed_config, deserialized_embed_config);
let state = EncoderState::new_zeros(5);
let serialized_state = serde_json::to_string(&state).unwrap();
let deserialized_state: EncoderState = serde_json::from_str(&serialized_state).unwrap();
assert_eq!(state, deserialized_state);
let rate_encoder = RateEncoder::new(2.0, 10.0, (0.0, 1.0));
let serialized_rate = serde_json::to_string(&rate_encoder).unwrap();
let deserialized_rate: RateEncoder = serde_json::from_str(&serialized_rate).unwrap();
assert_eq!(rate_encoder, deserialized_rate);
let delta_encoder = DeltaEncoder::new(0.5, 3);
let serialized_delta = serde_json::to_string(&delta_encoder).unwrap();
let deserialized_delta: DeltaEncoder = serde_json::from_str(&serialized_delta).unwrap();
assert_eq!(delta_encoder, deserialized_delta);
let pop_encoder = PopulationEncoder::new(5, (0.0, 1.0), 0.2);
let serialized_pop = serde_json::to_string(&pop_encoder).unwrap();
let deserialized_pop: PopulationEncoder = serde_json::from_str(&serialized_pop).unwrap();
assert_eq!(pop_encoder, deserialized_pop);
let pred_encoder =
PredictiveEncoder::new(10, vec![(1.0, 1), (2.0, 2)], 2).expect("valid PredictiveEncoder");
let serialized_pred = serde_json::to_string(&pred_encoder).unwrap();
let deserialized_pred: PredictiveEncoder = serde_json::from_str(&serialized_pred).unwrap();
assert_eq!(pred_encoder, deserialized_pred);
let temp_encoder = TemporalEncoder::new(6, vec![(0.5, 1)], 2);
let serialized_temp = serde_json::to_string(&temp_encoder).unwrap();
let deserialized_temp: TemporalEncoder = serde_json::from_str(&serialized_temp).unwrap();
assert_eq!(temp_encoder, deserialized_temp);
let gain_curve = GainCurve::new((0.0, 1.0), (0.5, 2.0));
let serialized_curve = serde_json::to_string(&gain_curve).unwrap();
let deserialized_curve: GainCurve = serde_json::from_str(&serialized_curve).unwrap();
assert_eq!(gain_curve, deserialized_curve);
let modulator_curves = ModulatorGainCurves {
threshold: Some(gain_curve),
sensitivity: Some(GainCurve::new((0.0, 1.0), (1.0, 1.5))),
firing_rate: Some(GainCurve::new((0.0, 1.0), (1.0, 2.5))),
latency: Some(GainCurve::new((0.0, 1.0), (1.0, 0.8))),
};
let serialized_modulator_curves = serde_json::to_string(&modulator_curves).unwrap();
let deserialized_modulator_curves: ModulatorGainCurves =
serde_json::from_str(&serialized_modulator_curves).unwrap();
assert_eq!(modulator_curves, deserialized_modulator_curves);
let encoding_gains = EncodingGains {
threshold_scale: 0.75,
sensitivity_scale: 1.25,
firing_rate_scale: 1.5,
latency_scale: 0.9,
};
let serialized_gains = serde_json::to_string(&encoding_gains).unwrap();
let deserialized_gains: EncodingGains = serde_json::from_str(&serialized_gains).unwrap();
assert_eq!(encoding_gains, deserialized_gains);
let neuromodulator_gain_curves = NeuromodulatorGainCurves {
dopamine: modulator_curves,
cortisol: ModulatorGainCurves {
threshold: Some(GainCurve::new((0.0, 1.0), (1.0, 0.5))),
..Default::default()
},
acetylcholine: ModulatorGainCurves {
firing_rate: Some(GainCurve::new((0.0, 1.0), (1.0, 1.2))),
..Default::default()
},
tempo: ModulatorGainCurves {
sensitivity: Some(GainCurve::new((0.0, 1.0), (1.0, 1.1))),
..Default::default()
},
};
let serialized_neuromodulator_gain_curves =
serde_json::to_string(&neuromodulator_gain_curves).unwrap();
let deserialized_neuromodulator_gain_curves: NeuromodulatorGainCurves =
serde_json::from_str(&serialized_neuromodulator_gain_curves).unwrap();
assert_eq!(
neuromodulator_gain_curves,
deserialized_neuromodulator_gain_curves
);
let latency_encoder = LatencyEncoder::new(12, (0.0, 1.0));
let serialized_latency = serde_json::to_string(&latency_encoder).unwrap();
let deserialized_latency: LatencyEncoder = serde_json::from_str(&serialized_latency).unwrap();
assert_eq!(latency_encoder, deserialized_latency);
let phase_encoder = PhaseEncoder::new(8, (0.0, 1.0));
let serialized_phase = serde_json::to_string(&phase_encoder).unwrap();
let deserialized_phase: PhaseEncoder = serde_json::from_str(&serialized_phase).unwrap();
assert_eq!(phase_encoder, deserialized_phase);
}
#[test]
fn test_serde_validation_failures() {
let invalid_pred_json = r#"{
"history": [[0.0]],
"thresholds": [],
"history_depth": 10,
"deviation_thresholds": []
}"#;
let res: Result<PredictiveEncoder, _> = serde_json::from_str(invalid_pred_json);
assert!(res.is_err());
let invalid_pred_depth_json = r#"{
"history": [[0.0]],
"thresholds": [0.0],
"history_depth": 2,
"deviation_thresholds": []
}"#;
let res: Result<PredictiveEncoder, _> = serde_json::from_str(invalid_pred_depth_json);
assert!(res.is_err());
let invalid_temp_depth_json = r#"{
"history": [[0.0]],
"history_depth": 5,
"change_thresholds": []
}"#;
let res: Result<TemporalEncoder, _> = serde_json::from_str(invalid_temp_depth_json);
assert!(res.is_err());
let invalid_derivative_json = r#"{
"last_values": [0.0],
"thresholds": [1.0, 2.0]
}"#;
let res: Result<DerivativeEncoder, _> = serde_json::from_str(invalid_derivative_json);
assert!(res.is_err());
let invalid_latency_json = r#"{
"max_latency": 5,
"range": [1.0, 0.5]
}"#;
let res: Result<LatencyEncoder, _> = serde_json::from_str(invalid_latency_json);
assert!(res.is_err());
let nonfinite_derivative_json = r#"{
"last_values": [0.0, 0.0],
"thresholds": [1e309, 1e309]
}"#;
let res: Result<DerivativeEncoder, _> = serde_json::from_str(nonfinite_derivative_json);
assert!(res.is_err());
let nonfinite_state_json = r#"{
"last_values": [1e309, 0.0],
"thresholds": [1.0, 2.0]
}"#;
let res: Result<DerivativeEncoder, _> = serde_json::from_str(nonfinite_state_json);
assert!(res.is_err());
let invalid_gain_curve_json = r#"{
"input_range": [1.0, 0.0],
"output_range": [0.0, 2.0]
}"#;
let res: Result<GainCurve, _> = serde_json::from_str(invalid_gain_curve_json);
assert!(res.is_err());
let valid_gain_curve_json = r#"{
"input_range": [0.0, 1.0],
"output_range": [0.0, 1.0]
}"#;
let res: Result<GainCurve, _> = serde_json::from_str(valid_gain_curve_json);
assert!(res.is_ok());
let invalid_phase_json = r#"{
"cycle_steps": 0,
"range": [0.0, 1.0],
"current_phase": 0
}"#;
let res: Result<PhaseEncoder, _> = serde_json::from_str(invalid_phase_json);
assert!(res.is_err());
let invalid_rate_json =
r#"{"base_rate":2.0,"max_rate":1.0,"range":[0.0,1.0],"accumulators":[]}"#;
let res: Result<RateEncoder, _> = serde_json::from_str(invalid_rate_json);
assert!(res.is_err());
let zero_delta_json = r#"{"last_values":[0.0],"threshold":0.0}"#;
let res: Result<DeltaEncoder, _> = serde_json::from_str(zero_delta_json);
assert!(res.is_ok());
let invalid_delta_json = r#"{"last_values":[0.0],"threshold":-1.0}"#;
let res: Result<DeltaEncoder, _> = serde_json::from_str(invalid_delta_json);
assert!(res.is_err());
let invalid_population_json = r#"{"num_neurons":0,"input_range":[0.0,1.0],"tuning_width":0.1}"#;
let res: Result<PopulationEncoder, _> = serde_json::from_str(invalid_population_json);
assert!(res.is_err());
let zero_latency_json = r#"{"max_latency":0,"range":[0.0,1.0]}"#;
let res: Result<LatencyEncoder, _> = serde_json::from_str(zero_latency_json);
assert!(res.is_ok());
let invalid_latency_json = r#"{"max_latency":1,"range":[1.0,1.0]}"#;
let res: Result<LatencyEncoder, _> = serde_json::from_str(invalid_latency_json);
assert!(res.is_err());
}
#[test]
#[cfg(feature = "serde")]
fn test_serde_embedding_rate_encoder() {
let config = EmbeddingEncoderConfig { v_th: 1.0 };
let embeddings = vec![0.5, 0.8];
let encoder = EmbeddingRateEncoder::new(&embeddings, config);
let serialized = serde_json::to_string(&encoder).unwrap();
let deserialized: EmbeddingRateEncoder = serde_json::from_str(&serialized).unwrap();
assert_eq!(encoder.config, deserialized.config);
assert_eq!(
encoder.normalized_embeddings,
deserialized.normalized_embeddings
);
}
#[test]
#[cfg(feature = "serde")]
fn test_serde_derivative_encoder() {
let encoder = DerivativeEncoder::new(vec![1.0, 2.0]);
let serialized = serde_json::to_string(&encoder).unwrap();
let deserialized: DerivativeEncoder = serde_json::from_str(&serialized).unwrap();
assert_eq!(encoder, deserialized);
}
#[test]
#[cfg(feature = "serde")]
fn test_serde_validation_errors_extended() {
let invalid_config_json = r#"{"v_th": 0.0}"#;
let res: Result<EmbeddingEncoderConfig, _> = serde_json::from_str(invalid_config_json);
assert!(res.is_err());
let invalid_rate_json = r#"{
"config": {"v_th": 1.0},
"normalized_embeddings": [1e309, 1e309]
}"#;
let res: Result<EmbeddingRateEncoder, _> = serde_json::from_str(invalid_rate_json);
assert!(res.is_err());
}
#[test]
#[cfg(feature = "serde")]
fn test_serde_poisson_encoder() {
let enc = PoissonEncoder::new(10);
let serialized = serde_json::to_string(&enc).unwrap();
let deserialized: PoissonEncoder = serde_json::from_str(&serialized).unwrap();
assert_eq!(enc.num_steps, deserialized.num_steps);
}
#[test]
#[cfg(feature = "serde")]
fn test_serde_neuromodulators() {
let nm = NeuroModulators {
dopamine: 0.5,
cortisol: 0.2,
acetylcholine: 0.8,
tempo: 1.0,
};
let serialized = serde_json::to_string(&nm).unwrap();
let deserialized: NeuroModulators = serde_json::from_str(&serialized).unwrap();
assert_eq!(nm, deserialized);
}
#[test]
fn test_rate_encoder_serde_rejects_invalid_dt_seconds() {
let value = serde_json::json!({
"base_rate": 0.0,
"max_rate": 10.0,
"range": [0.0, 1.0],
"dt_seconds": 0.0,
"accumulators": []
});
let result: Result<RateEncoder, _> = serde_json::from_value(value);
assert!(result.is_err());
}