corpus_ipc/models/
spikes.rs1use serde::{Deserialize, Serialize};
4
5use crate::validation::{
6 ProtocolLimits, Validate, ValidationError, check_count, check_finite, check_opt_string,
7};
8
9use super::BatchMetadata;
10use super::de::{
11 de_opt_session_id, de_spikes, de_strength, prefix_path, validate_optional_metadata,
12};
13
14#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
27#[serde(try_from = "SpikeBatchWire")]
28pub struct SpikeBatch {
29 pub session_id: Option<String>,
31 pub batch_id: u64,
33 pub timestamp: u64,
35 pub spikes: Vec<SpikeEvent>,
37 pub metadata: Option<BatchMetadata>,
39}
40
41#[derive(Deserialize)]
42struct SpikeBatchWire {
43 #[serde(default, deserialize_with = "de_opt_session_id")]
44 session_id: Option<String>,
45 batch_id: u64,
46 timestamp: u64,
47 #[serde(deserialize_with = "de_spikes")]
48 spikes: Vec<SpikeEvent>,
49 metadata: Option<BatchMetadata>,
50}
51
52impl TryFrom<SpikeBatchWire> for SpikeBatch {
53 type Error = ValidationError;
54
55 fn try_from(wire: SpikeBatchWire) -> Result<Self, Self::Error> {
56 let batch = SpikeBatch {
57 session_id: wire.session_id,
58 batch_id: wire.batch_id,
59 timestamp: wire.timestamp,
60 spikes: wire.spikes,
61 metadata: wire.metadata,
62 };
63 batch.validate()?;
64 Ok(batch)
65 }
66}
67
68impl Validate for SpikeBatch {
69 fn validate_with(&self, limits: ProtocolLimits) -> Result<(), ValidationError> {
70 check_opt_string("session_id", self.session_id.as_deref(), limits)?;
71 check_count("spikes", self.spikes.len(), limits.max_spike_events)?;
72 for (index, spike) in self.spikes.iter().enumerate() {
73 spike
74 .validate_with(limits)
75 .map_err(|err| prefix_path(err, &format!("spikes[{index}]")))?;
76 }
77 validate_optional_metadata(&self.metadata, limits, self.spikes.len())
78 }
79}
80
81pub type IpcSpikeBatch = SpikeBatch;
86
87#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
91#[serde(try_from = "SpikeEventWire")]
92pub struct SpikeEvent {
93 pub channel: u16,
95 pub time: u32,
97 pub strength: f32,
99}
100
101#[derive(Deserialize)]
102struct SpikeEventWire {
103 channel: u16,
104 time: u32,
105 #[serde(deserialize_with = "de_strength")]
106 strength: f32,
107}
108
109impl TryFrom<SpikeEventWire> for SpikeEvent {
110 type Error = ValidationError;
111
112 fn try_from(wire: SpikeEventWire) -> Result<Self, Self::Error> {
113 let event = SpikeEvent {
114 channel: wire.channel,
115 time: wire.time,
116 strength: wire.strength,
117 };
118 event.validate()?;
119 Ok(event)
120 }
121}
122
123impl Validate for SpikeEvent {
124 fn validate_with(&self, _limits: ProtocolLimits) -> Result<(), ValidationError> {
125 check_finite("strength", self.strength)
126 }
127}