Skip to content

Commit 1a29f76

Browse files
committed
feat(types): add rustmail_types crate for shared types
1 parent 25d7fac commit 1a29f76

16 files changed

Lines changed: 361 additions & 474 deletions

File tree

Cargo.lock

Lines changed: 27 additions & 467 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[workspace]
2-
members = ["rustmail", "rustmail_panel"]
2+
members = ["rustmail", "rustmail_panel", "rustmail_types"]
33
resolver = "3"

rustmail/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ edition = "2024"
55
license = "MIT"
66

77
[dependencies]
8+
rustmail_types = { path = "../rustmail_types" }
89
serde = { version = "*", features = ["derive"] }
910
serenity = "0.12.4"
1011
sqlx = { version = "0.8.6", features = ["runtime-tokio", "sqlite", "macros", "migrate"] }
@@ -24,8 +25,6 @@ serde_json = "1.0.145"
2425
rand = "0.8.5"
2526
base64 = "0.22.1"
2627
subtle = "2.6.1"
27-
chrono-tz = "0.10.4"
28-
console-subscriber = "0.4.1"
2928

3029
[dependencies.uuid]
3130
version = "1.18.1"

rustmail_panel/Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ edition = "2024"
55
license = "MIT"
66

77
[dependencies]
8+
rustmail_types = { path = "../rustmail_types" }
89
yew = { version = "0.21", features = ["csr"] }
910
yew-router = "0.18.0"
1011
wasm-bindgen-futures = "0.4.50"
1112
gloo-net = "0.6.0"
1213
gloo-utils = "0.2.0"
13-
web-sys = "0.3.77"
14+
web-sys = { version = "0.3.77", features = ["HtmlSelectElement"] }
1415
serde_json = "1.0.145"
1516
i18nrs = { version = "0.1.7", features = ["yew"] }
16-
tailyew = "0.1.38"
1717
serde = { version = "1.0.228", features = ["derive"] }
1818
js-sys = "0.3.77"
1919
wasm-bindgen = "0.2.100"
2020
urlencoding = "2.1.3"
2121
ammonia = "4.1.2"
2222
pulldown-cmark = "0.13.0"
23-
[build-dependencies]
24-
navigator = "0.3.0"
23+
chrono-tz = { version = "0.10", features = ["serde"] }
24+
[build-dependencies]

rustmail_types/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "rustmail_types"
3+
version = "0.1.1"
4+
edition = "2024"
5+
license = "MIT"
6+
7+
[dependencies]
8+
serde = { version = "1.0", features = ["derive"] }
9+
chrono-tz = { version = "0.10", features = ["serde"] }

rustmail_types/src/api/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use crate::config::*;
2+
use serde::{Deserialize, Serialize};
3+
4+
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
5+
pub struct ConfigResponse {
6+
pub bot: BotConfig,
7+
pub command: CommandConfig,
8+
pub thread: ThreadConfig,
9+
pub language: LanguageConfig,
10+
pub error_handling: ErrorHandlingConfig,
11+
pub notifications: NotificationsConfig,
12+
pub reminders: ReminderConfig,
13+
pub logs: LogsConfig,
14+
}

rustmail_types/src/config/bot.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
use chrono_tz::Tz;
2+
use serde::{Deserialize, Serialize};
3+
4+
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
5+
pub struct BotConfig {
6+
pub token: String,
7+
pub mode: ServerMode,
8+
pub status: String,
9+
pub welcome_message: String,
10+
pub close_message: String,
11+
pub typing_proxy_from_user: bool,
12+
pub typing_proxy_from_staff: bool,
13+
pub enable_logs: bool,
14+
pub enable_features: bool,
15+
pub enable_panel: bool,
16+
pub client_id: u64,
17+
pub client_secret: String,
18+
pub redirect_url: String,
19+
#[serde(
20+
default = "default_timezone",
21+
deserialize_with = "deserialize_timezone",
22+
serialize_with = "serialize_timezone"
23+
)]
24+
pub timezone: Tz,
25+
#[serde(default)]
26+
pub logs_channel_id: Option<u64>,
27+
#[serde(default)]
28+
pub features_channel_id: Option<u64>,
29+
#[serde(default)]
30+
pub ip: Option<String>,
31+
}
32+
33+
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
34+
#[serde(tag = "type", rename_all = "lowercase")]
35+
pub enum ServerMode {
36+
Single { guild_id: u64 },
37+
Dual {
38+
community_guild_id: u64,
39+
staff_guild_id: u64,
40+
},
41+
}
42+
43+
impl BotConfig {
44+
pub fn get_community_guild_id(&self) -> u64 {
45+
match &self.mode {
46+
ServerMode::Single { guild_id } => *guild_id,
47+
ServerMode::Dual { community_guild_id, .. } => *community_guild_id,
48+
}
49+
}
50+
51+
pub fn get_staff_guild_id(&self) -> u64 {
52+
match &self.mode {
53+
ServerMode::Single { guild_id } => *guild_id,
54+
ServerMode::Dual { staff_guild_id, .. } => *staff_guild_id,
55+
}
56+
}
57+
58+
pub fn is_dual_mode(&self) -> bool {
59+
matches!(self.mode, ServerMode::Dual { .. })
60+
}
61+
62+
pub fn validate_logs_config(&self) -> Result<(), String> {
63+
match (self.enable_logs, self.logs_channel_id) {
64+
(true, None) => {
65+
Err("'logs_channel_id' field is required if 'enable_logs' is true".to_string())
66+
}
67+
(false, Some(_)) => {
68+
Err("'logs_channel_id' must not be filled in if 'enable_logs' is false".to_string())
69+
}
70+
(true, Some(_)) => Ok(()),
71+
(false, None) => Ok(()),
72+
}
73+
}
74+
75+
pub fn validate_features_config(&self) -> Result<(), String> {
76+
match (self.enable_features, self.features_channel_id) {
77+
(true, None) => Err(
78+
"'features_channel_id' field is required if 'enable_features' is true".to_string(),
79+
),
80+
(false, Some(_)) => Err(
81+
"'features_channel_id' must not be filled in if 'enable_features' is false"
82+
.to_string(),
83+
),
84+
(true, Some(_)) => Ok(()),
85+
(false, None) => Ok(()),
86+
}
87+
}
88+
89+
pub fn is_community_guild(&self, guild_id: u64) -> bool {
90+
match &self.mode {
91+
ServerMode::Single { guild_id: gid } => *gid == guild_id,
92+
ServerMode::Dual { community_guild_id, .. } => *community_guild_id == guild_id,
93+
}
94+
}
95+
}
96+
97+
fn deserialize_timezone<'de, D>(deserializer: D) -> Result<Tz, D::Error>
98+
where
99+
D: serde::Deserializer<'de>,
100+
{
101+
let s: String = Deserialize::deserialize(deserializer)?;
102+
s.parse::<Tz>().map_err(serde::de::Error::custom)
103+
}
104+
105+
fn serialize_timezone<S>(tz: &Tz, serializer: S) -> Result<S::Ok, S::Error>
106+
where
107+
S: serde::Serializer,
108+
{
109+
serializer.serialize_str(&tz.to_string())
110+
}
111+
112+
fn default_timezone() -> Tz {
113+
chrono_tz::UTC
114+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use serde::{Deserialize, Serialize};
2+
3+
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
4+
pub struct CommandConfig {
5+
pub prefix: String,
6+
}
7+
8+
impl Default for CommandConfig {
9+
fn default() -> Self {
10+
Self {
11+
prefix: "!".to_string(),
12+
}
13+
}
14+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use serde::{Deserialize, Serialize};
2+
3+
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
4+
pub struct ErrorHandlingConfig {
5+
pub show_detailed_errors: bool,
6+
pub log_errors: bool,
7+
pub send_error_embeds: bool,
8+
pub auto_delete_error_messages: bool,
9+
pub error_message_ttl: Option<u64>,
10+
#[serde(default = "default_display_errors")]
11+
pub display_errors: bool,
12+
}
13+
14+
fn default_display_errors() -> bool {
15+
true
16+
}
17+
18+
impl Default for ErrorHandlingConfig {
19+
fn default() -> Self {
20+
Self {
21+
show_detailed_errors: true,
22+
log_errors: true,
23+
send_error_embeds: true,
24+
auto_delete_error_messages: false,
25+
error_message_ttl: None,
26+
display_errors: true,
27+
}
28+
}
29+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use serde::{Deserialize, Serialize};
2+
3+
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
4+
pub struct LanguageConfig {
5+
pub default_language: String,
6+
pub fallback_language: String,
7+
pub supported_languages: Vec<String>,
8+
}
9+
10+
impl Default for LanguageConfig {
11+
fn default() -> Self {
12+
Self {
13+
default_language: "en".to_string(),
14+
fallback_language: "en".to_string(),
15+
supported_languages: vec!["en".to_string(), "fr".to_string()],
16+
}
17+
}
18+
}

0 commit comments

Comments
 (0)