emotiv_cortex_v2/protocol/
training.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy)]
7pub enum DetectionType {
8 MentalCommand,
10 FacialExpression,
12}
13
14impl DetectionType {
15 #[must_use]
17 pub fn as_str(&self) -> &'static str {
18 match self {
19 DetectionType::MentalCommand => "mentalCommand",
20 DetectionType::FacialExpression => "facialExpression",
21 }
22 }
23}
24
25#[derive(Debug, Clone, Copy)]
27pub enum TrainingStatus {
28 Start,
30 Accept,
32 Reject,
34 Reset,
36 Erase,
38}
39
40impl TrainingStatus {
41 #[must_use]
43 pub fn as_str(&self) -> &'static str {
44 match self {
45 TrainingStatus::Start => "start",
46 TrainingStatus::Accept => "accept",
47 TrainingStatus::Reject => "reject",
48 TrainingStatus::Reset => "reset",
49 TrainingStatus::Erase => "erase",
50 }
51 }
52}
53
54#[derive(Debug, Clone, Deserialize)]
56pub struct DetectionInfo {
57 pub actions: Vec<String>,
59 pub controls: Vec<String>,
61 pub events: Vec<String>,
63}
64#[derive(Debug, Clone, Deserialize)]
66pub struct TrainedSignatureActions {
67 #[serde(rename = "totalTimesTraining")]
69 pub total_times_training: u32,
70
71 #[serde(rename = "trainedActions")]
73 pub trained_actions: Vec<TrainedAction>,
74}
75
76#[derive(Debug, Clone, Deserialize)]
78pub struct TrainedAction {
79 pub action: String,
81 pub times: u32,
83}
84
85#[derive(Debug, Clone, Deserialize)]
87pub struct TrainingTime {
88 pub time: f64,
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct MentalCommandTrainingThresholdRequest {
95 pub session_id: Option<String>,
97 pub profile: Option<String>,
99 pub status: Option<String>,
101 pub value: Option<f64>,
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct FacialExpressionSignatureTypeRequest {
108 pub status: String,
110 pub profile: Option<String>,
112 pub session: Option<String>,
114 pub signature: Option<String>,
116}
117
118#[derive(Debug, Clone, Serialize, Deserialize)]
120pub struct FacialExpressionThresholdRequest {
121 pub status: String,
123 pub action: String,
125 pub profile: Option<String>,
127 pub session: Option<String>,
129 pub value: Option<u32>,
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 #[test]
138 fn test_detection_type_strings() {
139 assert_eq!(DetectionType::MentalCommand.as_str(), "mentalCommand");
140 assert_eq!(DetectionType::FacialExpression.as_str(), "facialExpression");
141 }
142
143 #[test]
144 fn test_training_status_strings() {
145 assert_eq!(TrainingStatus::Start.as_str(), "start");
146 assert_eq!(TrainingStatus::Accept.as_str(), "accept");
147 assert_eq!(TrainingStatus::Reject.as_str(), "reject");
148 assert_eq!(TrainingStatus::Reset.as_str(), "reset");
149 assert_eq!(TrainingStatus::Erase.as_str(), "erase");
150 }
151 #[test]
152 fn test_deserialize_trained_signature_actions() {
153 let json = r#"{
154 "totalTimesTraining": 15,
155 "trainedActions": [
156 {"action": "neutral", "times": 8},
157 {"action": "push", "times": 4},
158 {"action": "pull", "times": 3}
159 ]
160 }"#;
161
162 let actions: TrainedSignatureActions = serde_json::from_str(json).unwrap();
163 assert_eq!(actions.total_times_training, 15);
164 assert_eq!(actions.trained_actions.len(), 3);
165 assert_eq!(actions.trained_actions[0].action, "neutral");
166 assert_eq!(actions.trained_actions[0].times, 8);
167 assert_eq!(actions.trained_actions[2].action, "pull");
168 }
169
170 #[test]
171 fn test_deserialize_training_time() {
172 let json = r#"{"time": 8.0}"#;
173
174 let tt: TrainingTime = serde_json::from_str(json).unwrap();
175 assert!((tt.time - 8.0).abs() < f64::EPSILON);
176 }
177}