use serde_json::json;
#[rustfmt::skip]
#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, strum_macros::EnumString, )]
#[strum(ascii_case_insensitive)]
pub enum Level {
Msg,
Err,
Info,
Warn,
}
#[rustfmt::skip]
#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, strum_macros::EnumString, )]
#[strum(ascii_case_insensitive)]
pub enum Ty {
ServerTime, Connected, Disconnect,
Accept, Success, Failed,
Notification,
ChatMessage, HistoryMessage, HistoryTalk,
UserOnline, UserOffline,
Location, }
#[derive(serde::Serialize, serde::Deserialize)]
pub enum TypedMessage {
TextMessage(String),
JsonMessage(serde_json::Value),
}
#[derive(serde::Serialize, serde::Deserialize)]
pub struct OutputMessage {
pub id: Option<String>,
pub level: Level,
pub ty: Ty,
pub msg: Option<String>,
pub data: Option<serde_json::Value>,
}
impl From<OutputMessage> for bytestring::ByteString {
fn from(val: OutputMessage) -> Self {
let json_string = serde_json::to_string(&val).unwrap();
let byte_string: bytestring::ByteString = bytestring::ByteString::from(json_string);
byte_string
}
}
impl OutputMessage {
pub fn err(ty: Ty, msg: &str, id: Option<String>) -> Self {
OutputMessage {
id,
level: Level::Err,
ty,
msg: Some(msg.to_string()),
data: None,
}
}
pub fn message(&self) -> Option<String> {
let mut vl = json! ({"level": self.level, "ty": self.ty});
if let Some(id) = &self.id {
vl["id"] = json!(id);
}
if let Some(data) = &self.data {
vl["data"] = data.clone();
if let Some(obj) = vl["data"].as_object_mut() {
obj.remove("id");
}
}
if let Some(msg) = &self.msg {
vl["msg"] = json!(msg);
}
vl["@ts"] = json!(Self::ts());
Some(serde_json::to_string(&vl).unwrap())
}
pub fn ts() -> String {
chrono::Utc::now()
.format("%Y-%m-%dT%H:%M:%S.%3f")
.to_string()
+ "Z"
}
}