use plexor_codec_serde_postcard::SerdePostcardCodec;
use plexor_core::namespace::NamespaceImpl;
use plexor_core::neuron::{Neuron, NeuronImpl};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct SerdeStruct {
num: i32,
text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct ApiResponse {
status: String,
code: u16,
data: Option<String>,
timestamp: u64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct TaskResult {
task_id: String,
success: bool,
result: Option<HashMap<String, String>>,
error: Option<String>,
execution_time_ms: u64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct MetricsReport {
service_name: String,
cpu_usage: f64,
memory_mb: u64,
request_count: u64,
error_rate: f32,
uptime_seconds: u64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct UserEvent {
user_id: String,
event_type: String,
properties: HashMap<String, String>,
session_id: Option<String>,
timestamp: chrono::DateTime<chrono::Utc>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct NotificationPayload {
recipient_id: String,
message: String,
priority: NotificationPriority,
channels: Vec<String>,
metadata: Option<HashMap<String, String>>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
enum NotificationPriority {
Low,
Normal,
High,
Critical,
}
#[test]
fn test_postcard_neuron() {
let ms = SerdeStruct {
num: 42,
text: "Hello, plexor!".to_string(),
};
let ns = NamespaceImpl {
delimiter: ".",
parts: vec!["dev", "plexo"],
};
let neuron: NeuronImpl<SerdeStruct, SerdePostcardCodec> =
NeuronImpl::new(Arc::new(ns.clone()));
assert_eq!(neuron.name(), "dev.plexo.SerdeStruct.postcard");
assert_eq!(neuron.name_without_codec(), "dev.plexo.SerdeStruct");
let encoded = neuron.encode(&ms).expect("Encoding should succeed");
let decoded = neuron
.decode(&encoded)
.expect("Decoding should succeed");
assert_eq!(decoded.num, ms.num);
assert_eq!(decoded.text, ms.text);
}
#[test]
fn test_api_response_postcard_codec() {
let response = ApiResponse {
status: "success".to_string(),
code: 200,
data: Some("Operation completed".to_string()),
timestamp: 1609459200,
};
let ns = NamespaceImpl {
delimiter: ".",
parts: vec!["api", "v1"],
};
let neuron: NeuronImpl<ApiResponse, SerdePostcardCodec> = NeuronImpl::new(Arc::new(ns));
assert_eq!(neuron.name(), "api.v1.ApiResponse.postcard");
let encoded = neuron.encode(&response).expect("Encoding should succeed");
let decoded = neuron.decode(&encoded).expect("Decoding should succeed");
assert_eq!(decoded, response);
}
#[test]
fn test_task_result_postcard_codec() {
let mut result_data = HashMap::new();
result_data.insert("output".to_string(), "processed 100 items".to_string());
result_data.insert("duration".to_string(), "5.2s".to_string());
let task = TaskResult {
task_id: "task_12345".to_string(),
success: true,
result: Some(result_data),
error: None,
execution_time_ms: 5200,
};
let ns = NamespaceImpl {
delimiter: ".",
parts: vec!["worker", "tasks"],
};
let neuron: NeuronImpl<TaskResult, SerdePostcardCodec> = NeuronImpl::new(Arc::new(ns));
assert_eq!(neuron.name(), "worker.tasks.TaskResult.postcard");
let encoded = neuron.encode(&task).expect("Encoding should succeed");
let decoded = neuron.decode(&encoded).expect("Decoding should succeed");
assert_eq!(decoded, task);
}
#[test]
fn test_metrics_report_postcard_codec() {
let metrics = MetricsReport {
service_name: "api-gateway".to_string(),
cpu_usage: 75.5,
memory_mb: 512,
request_count: 10000,
error_rate: 0.02,
uptime_seconds: 3600,
};
let ns = NamespaceImpl {
delimiter: ".",
parts: vec!["monitoring"],
};
let neuron: NeuronImpl<MetricsReport, SerdePostcardCodec> = NeuronImpl::new(Arc::new(ns));
assert_eq!(neuron.name(), "monitoring.MetricsReport.postcard");
let encoded = neuron.encode(&metrics).expect("Encoding should succeed");
let decoded = neuron.decode(&encoded).expect("Decoding should succeed");
assert_eq!(decoded, metrics);
}
#[test]
fn test_user_event_postcard_codec() {
let mut properties = HashMap::new();
properties.insert(
"page".to_string(),
"homepage".to_string(),
);
properties.insert(
"duration".to_string(),
"120".to_string(),
);
let event = UserEvent {
user_id: "user_789".to_string(),
event_type: "page_view".to_string(),
properties,
session_id: Some("session_abc123".to_string()),
timestamp: chrono::Utc::now(),
};
let ns = NamespaceImpl {
delimiter: ".",
parts: vec!["analytics"],
};
let neuron: NeuronImpl<UserEvent, SerdePostcardCodec> = NeuronImpl::new(Arc::new(ns));
assert_eq!(neuron.name(), "analytics.UserEvent.postcard");
let encoded = neuron.encode(&event).expect("Encoding should succeed");
let decoded = neuron.decode(&encoded).expect("Decoding should succeed");
assert_eq!(decoded.user_id, event.user_id);
assert_eq!(decoded.event_type, event.event_type);
assert_eq!(decoded.properties, event.properties);
assert_eq!(decoded.session_id, event.session_id);
}
#[test]
fn test_notification_payload_postcard_codec() {
let mut metadata = HashMap::new();
metadata.insert("campaign_id".to_string(), "promo_2024".to_string());
let notification = NotificationPayload {
recipient_id: "user_456".to_string(),
message: "Your order has been shipped!".to_string(),
priority: NotificationPriority::High,
channels: vec!["email".to_string(), "push".to_string()],
metadata: Some(metadata),
};
let ns = NamespaceImpl {
delimiter: ".",
parts: vec!["notifications"],
};
let neuron: NeuronImpl<NotificationPayload, SerdePostcardCodec> = NeuronImpl::new(Arc::new(ns));
assert_eq!(neuron.name(), "notifications.NotificationPayload.postcard");
let encoded = neuron
.encode(¬ification)
.expect("Encoding should succeed");
let decoded = neuron.decode(&encoded).expect("Decoding should succeed");
assert_eq!(decoded, notification);
}
#[test]
fn test_notification_priority_enum_roundtrip() {
let original = NotificationPriority::Critical;
let encoded = postcard::to_allocvec(&original).expect("Should encode");
let decoded: NotificationPriority = postcard::from_bytes(&encoded).expect("Should decode");
assert_eq!(original, decoded);
}