use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub enum MessageType {
Data,
Config,
Process,
Invalid,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub enum SubMessageType {
Normal,
Reply,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConfigMessageType {
Connect,
Disconnect,
Field,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub enum ProcessMessageType {
Stop,
Suspend,
Restart,
}
pub trait MessageSerializer {
fn make_self_from_string<'a, T>(json_string: &'a str) -> T
where
T: std::marker::Sized + serde::Deserialize<'a>,
{
serde_json::from_str(json_string).unwrap()
}
fn make_message(&self, msg_type: MessageType) -> IIDMessage
where
Self: std::marker::Sized + serde::Serialize,
{
let struct_string = serde_json::to_string(&self).unwrap();
IIDMessage::new(msg_type, Some(struct_string))
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct IIDMessage {
msg_type: MessageType,
sub_msg_type: SubMessageType,
payload: Option<String>,
}
impl IIDMessage {
pub fn new(msg_type: MessageType, payload: Option<String>) -> Self {
IIDMessage {
msg_type,
sub_msg_type: SubMessageType::Normal,
payload,
}
}
pub fn msg_type(&self) -> MessageType {
self.msg_type
}
pub fn sub_msg_type(&self) -> SubMessageType {
self.sub_msg_type
}
pub fn payload(&self) -> &Option<String> {
&self.payload
}
pub fn sub_msg_type_mut(&mut self) -> &mut SubMessageType {
&mut self.sub_msg_type
}
}
#[derive(Clone, Serialize, Deserialize)]
pub struct FieldConfiguration {
field_name: String,
config_string: String,
}
impl FieldConfiguration {
pub fn new(field_name: String, config_string: String) -> Self {
FieldConfiguration {
field_name,
config_string,
}
}
pub fn get_field_name(&self) -> String {
self.field_name.clone()
}
pub fn set_field_name(&mut self, new_field: String) {
self.field_name = new_field.clone();
}
pub fn get_config_string(&self) -> String {
self.config_string.clone()
}
pub fn set_config_string(&mut self, new_config: String) {
self.config_string = new_config.clone();
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ConfigMessage {
msg_type: ConfigMessageType,
data: Option<String>,
}
impl ConfigMessage {
pub fn new(msg_type: ConfigMessageType, data: Option<String>) -> Self {
ConfigMessage { msg_type, data }
}
pub fn msg_type(&self) -> ConfigMessageType {
self.msg_type
}
pub fn data(&self) -> &Option<String> {
&self.data
}
}
impl MessageSerializer for ConfigMessage {}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ProcessMessage {
msg: ProcessMessageType,
propagate: bool,
pub message_node: Option<Uuid>,
}
impl ProcessMessage {
pub fn new(msg: ProcessMessageType, propagate: bool) -> Self {
ProcessMessage {
msg,
propagate,
message_node: None,
}
}
pub fn msg(&self) -> ProcessMessageType {
self.msg
}
pub fn propagate(&self) -> bool {
self.propagate
}
pub fn message_node(&self) -> &Option<Uuid> {
&self.message_node
}
}
impl MessageSerializer for ProcessMessage {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_iidmessage() {
let msg_string = "foo".to_string();
let mut msg = IIDMessage::new(MessageType::Data, Some(msg_string.clone()));
assert_eq!(msg.msg_type(), MessageType::Data);
assert_eq!(msg.payload().is_none(), false);
assert_eq!(*msg.payload().as_ref().unwrap(), msg_string);
assert_eq!(msg.sub_msg_type(), SubMessageType::Normal);
*msg.sub_msg_type_mut() = SubMessageType::Reply;
assert_eq!(msg.sub_msg_type(), SubMessageType::Reply);
}
#[test]
fn test_config_message() {
let config_data = "{\"log_file_path\":\"Log_file.txt\"}".to_string();
let config_msg = ConfigMessage::new(ConfigMessageType::Field, Some(config_data.clone()));
assert_eq!(config_msg.msg_type(), ConfigMessageType::Field);
assert!(config_msg.data().is_some());
assert_eq!(*config_msg.data().as_ref().unwrap(), config_data);
let a_msg = config_msg.make_message(MessageType::Config);
assert_eq!(a_msg.msg_type(), MessageType::Config);
assert!(a_msg.payload().is_some());
let a_config_msg: ConfigMessage =
ConfigMessage::make_self_from_string(a_msg.payload().as_ref().unwrap().as_str());
assert_eq!(a_config_msg.msg_type(), ConfigMessageType::Field);
assert!(a_config_msg.data().is_some());
assert_eq!(*a_config_msg.data().as_ref().unwrap(), config_data);
}
#[test]
fn test_process_message() {
let prop_msg = ProcessMessage::new(ProcessMessageType::Stop, true);
assert_eq!(prop_msg.msg(), ProcessMessageType::Stop);
assert!(prop_msg.propagate());
let a_msg = prop_msg.make_message(MessageType::Process);
assert_eq!(a_msg.msg_type(), MessageType::Process);
assert!(a_msg.payload().is_some());
let a_prop_msg: ProcessMessage =
ProcessMessage::make_self_from_string(a_msg.payload().as_ref().unwrap().as_str());
assert_eq!(a_prop_msg.msg(), ProcessMessageType::Stop);
assert!(a_prop_msg.propagate());
}
}