use serde::{Deserialize, Deserializer, Serialize};
use std::collections::HashMap;
pub mod callback_message;
pub mod event_message;
pub mod system_message;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DownStreamMessage {
#[serde(rename = "specVersion")]
pub spec_version: Option<String>,
pub headers: MessageHeaders,
#[serde(rename = "type")]
pub r#type: MessageType,
pub data: Option<String>,
#[serde(flatten)]
pub extensions: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum MessageType {
#[serde(rename = "SYSTEM")]
System,
#[serde(rename = "EVENT")]
Event,
#[serde(rename = "CALLBACK")]
Callback,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Data {
System(callback_message::MessageData),
Event(event_message::EventMessage),
Callback(callback_message::CallbackMessage),
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct MessageHeaders {
#[serde(rename = "appId", skip_serializing_if = "Option::is_none")]
pub app_id: Option<String>,
#[serde(rename = "connectionId", skip_serializing_if = "Option::is_none")]
pub connection_id: Option<String>,
#[serde(rename = "contentType", skip_serializing_if = "Option::is_none")]
pub content_type: Option<String>,
#[serde(rename = "messageId", skip_serializing_if = "Option::is_none")]
pub message_id: Option<String>,
#[serde(rename = "time", skip_serializing_if = "Option::is_none")]
pub time: Option<String>,
#[serde(rename = "topic", skip_serializing_if = "Option::is_none")]
pub topic: Option<MessageTopic>,
#[serde(rename = "eventBornTime", skip_serializing_if = "Option::is_none")]
pub event_born_time: Option<i64>,
#[serde(rename = "eventCorpId", skip_serializing_if = "Option::is_none")]
pub event_corp_id: Option<String>,
#[serde(rename = "eventId", skip_serializing_if = "Option::is_none")]
pub event_id: Option<String>,
#[serde(rename = "eventType", skip_serializing_if = "Option::is_none")]
pub event_type: Option<String>,
#[serde(rename = "eventUnifiedAppId", skip_serializing_if = "Option::is_none")]
pub event_unified_app_id: Option<String>,
#[serde(flatten)]
pub extensions: HashMap<String, serde_json::Value>,
}
impl MessageHeaders {
pub fn new() -> Self {
Self::default()
}
pub fn with_message_id(mut self, message_id: String) -> Self {
self.message_id = Some(message_id);
self
}
pub fn with_content_type(mut self, content_type: &str) -> Self {
self.content_type = Some(content_type.to_string());
self
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Hash)]
#[serde(untagged)]
pub enum MessageTopic {
#[serde(rename = "CONNECTED")]
Connected,
#[serde(rename = "REGISTERED")]
Registered,
#[serde(rename = "disconnect")]
Disconnect,
#[serde(rename = "KEEPALIVE")]
KeepAlive,
#[serde(rename = "ping")]
Ping,
Callback(String),
}
impl From<String> for MessageTopic {
fn from(s: String) -> Self {
let uppercase = s.to_uppercase();
match uppercase.as_str() {
"CONNECTED" => MessageTopic::Connected,
"REGISTERED" => MessageTopic::Registered,
"DISCONNECT" => MessageTopic::Disconnect,
"KEEPALIVE" => MessageTopic::KeepAlive,
"PING" => MessageTopic::Ping,
_ => MessageTopic::Callback(s),
}
}
}
impl<'de> Deserialize<'de> for MessageTopic {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let str = String::deserialize(deserializer)?;
Ok(Self::from(str))
}
}
impl std::fmt::Display for MessageTopic {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let str = match self {
MessageTopic::Connected => "CONNECTED",
MessageTopic::Registered => "REGISTERED",
MessageTopic::Disconnect => "disconnect",
MessageTopic::KeepAlive => "KEEPALIVE",
MessageTopic::Ping => "ping",
MessageTopic::Callback(s) => s,
};
write!(f, "{str}")
}
}