1use chrono::prelude::*;
2use log::Level;
3use rs_data_formats_derive::Name;
4use serde::{Deserialize, Serialize};
5use serde_json::json;
6
7pub const TOPIC_PREFIX: &str = concat!("tg/", env!("CARGO_PKG_VERSION_MAJOR"), "/");
8
9pub trait Name {
10 fn name(&self) -> &'static str;
11}
12
13#[derive(Serialize, Deserialize, Debug)]
14pub enum Action {
15 Insert,
16 Update,
17 Delete,
18}
19
20#[derive(Serialize, Deserialize, Debug)]
21pub struct Common<T> {
22 pub sender: String,
23 pub application: String,
24 pub time: DateTime<Utc>,
25 pub identifier: Option<String>,
26 pub payload: T,
27 pub action: Action,
28}
29
30#[derive(Serialize, Deserialize, Debug, Name)]
31pub struct Log {
32 pub severity: Level,
33 pub msg: String,
34}
35
36#[derive(Serialize, Deserialize, Debug, Name)]
37pub struct Kovaak {
38 pub score: f32,
39 pub scenario: String,
40 pub game_version: String,
41}
42
43#[derive(Serialize, Deserialize, Debug, Name)]
44pub struct Homecounter {
45 pub name: String,
47 pub tab: String,
49 pub quantity: i32,
50}
51
52fn topic_name<T: Name>(prefix: &str, sym: &T) -> String {
53 format!("{}{}", prefix, sym.name().to_lowercase())
54}
55
56pub fn build_msg<T: Name + Serialize>(
57 sender: &str,
58 data: T,
59 action: Action,
60 time: Option<DateTime<Utc>>,
61 identifier: Option<String>,
62) -> (String, String) {
63 (
64 topic_name(TOPIC_PREFIX, &data),
65 json!(Common {
66 sender: sender.to_string(),
67 time: time.unwrap_or_else(Utc::now),
68 identifier,
69 application: data.name().to_lowercase(),
70 payload: data,
71 action
72 })
73 .to_string(),
74 )
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn test_topic_name() {
83 let k = Kovaak {
84 score: 0.0,
85 scenario: format!(""),
86 game_version: format!(""),
87 };
88 assert_eq!("Kovaak", topic_name(TOPIC_PREFIX, &k));
89 }
90}