173 lines
5.9 KiB
Rust
173 lines
5.9 KiB
Rust
use crate::config::MessageConfig;
|
|
use crate::game::player_data::PlayerData;
|
|
use crate::GlobalData;
|
|
use chrono::{DateTime, Utc};
|
|
use serde::{Deserialize, Serialize};
|
|
use serenity::model::guild::Member;
|
|
use serenity::prelude::Mentionable;
|
|
use std::collections::HashMap;
|
|
use tera::{Tera, Value};
|
|
|
|
type TeraFnRet = Box<dyn Fn(&HashMap<String, Value>) -> tera::Result<Value> + Send + Sync>;
|
|
|
|
fn time_to_discord_time(time_flag: &str) -> TeraFnRet {
|
|
let time_flag = time_flag.to_string();
|
|
|
|
Box::new(
|
|
move |args: &HashMap<String, Value>| -> tera::Result<Value> {
|
|
match args.get("time") {
|
|
Some(val) => match tera::from_value::<String>(val.clone()) {
|
|
Ok(v) => {
|
|
let time = v.parse::<DateTime<Utc>>().unwrap();
|
|
|
|
Ok(
|
|
tera::to_value(format!("<t:{}:{}>", time.timestamp(), time_flag))
|
|
.unwrap(),
|
|
)
|
|
}
|
|
Err(_) => Err("Failed to parse value as time".into()),
|
|
},
|
|
None => Err("Missing parameter".into()),
|
|
}
|
|
},
|
|
)
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct DiscordUser {
|
|
pub(crate) display_name: String,
|
|
pub(crate) mention: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Tally {
|
|
target: String,
|
|
votes: u64,
|
|
}
|
|
|
|
impl From<&Member> for DiscordUser {
|
|
fn from(m: &Member) -> Self {
|
|
Self {
|
|
display_name: m.display_name().to_string(),
|
|
mention: m.mention().to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct MessageTemplates {
|
|
templates: Tera,
|
|
}
|
|
|
|
impl MessageTemplates {
|
|
pub fn build_welcome_message(
|
|
&self,
|
|
global_data: &GlobalData,
|
|
discord_user: &DiscordUser,
|
|
player_data: &PlayerData,
|
|
) -> Result<String, tera::Error> {
|
|
let mut context = tera::Context::new();
|
|
context.insert("game_cfg", global_data.game_cfg().unwrap());
|
|
context.insert("game_state", global_data.game_state().unwrap());
|
|
context.insert("discord_user", discord_user);
|
|
context.insert("player_data", player_data);
|
|
let mut msg = self.templates.render("welcome_message", &context)?;
|
|
msg.push_str(&self.templates.render("status_message", &context)?);
|
|
|
|
Ok(msg)
|
|
}
|
|
|
|
pub fn build_satus_message(&self, global_data: &GlobalData) -> Result<String, tera::Error> {
|
|
let mut context = tera::Context::new();
|
|
context.insert("game_cfg", global_data.game_cfg().unwrap());
|
|
context.insert("game_state", global_data.game_state().unwrap());
|
|
self.templates.render("status_message", &context)
|
|
}
|
|
|
|
pub fn build_announcement(
|
|
&self,
|
|
global_data: &GlobalData,
|
|
message: &str,
|
|
) -> Result<String, tera::Error> {
|
|
let mut context = tera::Context::new();
|
|
context.insert("game_cfg", global_data.game_cfg().unwrap());
|
|
context.insert("game_state", global_data.game_state().unwrap());
|
|
context.insert("message", message);
|
|
self.templates.render("announcement", &context)
|
|
}
|
|
|
|
pub fn build_vote_tally(&self, global_data: &GlobalData) -> Result<String, tera::Error> {
|
|
let mut context = tera::Context::new();
|
|
context.insert("game_cfg", global_data.game_cfg().unwrap());
|
|
context.insert("game_state", global_data.game_state().unwrap());
|
|
context.insert(
|
|
"tallies",
|
|
&global_data.game_state().unwrap().get_vote_tallies(),
|
|
);
|
|
|
|
self.templates.render("tally_message", &context)
|
|
}
|
|
|
|
pub fn build_vote_message(
|
|
&self,
|
|
global_data: &GlobalData,
|
|
player: &PlayerData,
|
|
target: &PlayerData,
|
|
) -> Result<String, tera::Error> {
|
|
let mut context = tera::Context::new();
|
|
context.insert("game_cfg", global_data.game_cfg().unwrap());
|
|
context.insert("game_state", global_data.game_state().unwrap());
|
|
context.insert("player_data", player);
|
|
context.insert("target_data", target);
|
|
|
|
self.templates.render("vote_message", &context)
|
|
}
|
|
|
|
pub fn build_phase_extend_message(
|
|
&self,
|
|
global_data: &GlobalData,
|
|
) -> Result<String, tera::Error> {
|
|
let mut context = tera::Context::new();
|
|
context.insert("game_cfg", global_data.game_cfg().unwrap());
|
|
context.insert("game_state", global_data.game_state().unwrap());
|
|
|
|
self.templates.render("phase_extend_message", &context)
|
|
}
|
|
|
|
pub fn build_name(
|
|
&self,
|
|
global_data: &GlobalData,
|
|
first_name: Option<String>,
|
|
last_name: Option<String>,
|
|
) -> Result<String, tera::Error> {
|
|
let mut context = tera::Context::new();
|
|
context.insert("game_cfg", global_data.game_cfg().unwrap());
|
|
context.insert("first_name", &first_name);
|
|
context.insert("last_name", &last_name);
|
|
|
|
self.templates.render("name_format", &context)
|
|
}
|
|
}
|
|
|
|
impl TryFrom<MessageConfig> for MessageTemplates {
|
|
type Error = tera::Error;
|
|
|
|
fn try_from(config: MessageConfig) -> Result<Self, Self::Error> {
|
|
let mut templates = Tera::default();
|
|
|
|
templates.register_function("to_countdown", time_to_discord_time("R"));
|
|
templates.register_function("to_local_time", time_to_discord_time("f"));
|
|
|
|
templates.add_raw_template("welcome_message", &config.welcome_message)?;
|
|
templates.add_raw_template("status_message", &config.status_message)?;
|
|
templates.add_raw_template("announcement", &config.announcement_format)?;
|
|
templates.add_raw_template("tally_message", &config.tally_message)?;
|
|
templates.add_raw_template("vote_message", &config.vote_message)?;
|
|
templates.add_raw_template("phase_extend_message", &config.phase_extend_message)?;
|
|
|
|
templates.add_raw_template("name_format", &config.name_format)?;
|
|
|
|
Ok(Self { templates })
|
|
}
|
|
}
|