mirror of
https://github.com/Noratrieb/discord-court-bot.git
synced 2026-01-17 03:15:01 +01:00
rewrite to use sane ids in model
This commit is contained in:
parent
dda41f0006
commit
1f6021b555
3 changed files with 118 additions and 38 deletions
|
|
@ -197,11 +197,11 @@ async fn lawsuit_command_handler(
|
||||||
UserOption::get_optional(options.get(5)).wrap_err("accused_layer")?;
|
UserOption::get_optional(options.get(5)).wrap_err("accused_layer")?;
|
||||||
|
|
||||||
let mut lawsuit = Lawsuit {
|
let mut lawsuit = Lawsuit {
|
||||||
plaintiff: plaintiff.0.id.to_string(),
|
plaintiff: plaintiff.id.into(),
|
||||||
accused: accused.0.id.to_string(),
|
accused: accused.id.into(),
|
||||||
judge: judge.0.id.to_string(),
|
judge: judge.id.into(),
|
||||||
plaintiff_layer: plaintiff_layer.map(|l| l.0.id.to_string()),
|
plaintiff_layer: plaintiff_layer.map(|user| user.id.into()),
|
||||||
accused_layer: accused_layer.map(|l| l.0.id.to_string()),
|
accused_layer: accused_layer.map(|user| user.id.into()),
|
||||||
reason: reason.to_owned(),
|
reason: reason.to_owned(),
|
||||||
state: LawsuitState::Initial,
|
state: LawsuitState::Initial,
|
||||||
court_room: None,
|
court_room: None,
|
||||||
|
|
@ -228,7 +228,7 @@ async fn lawsuit_command_handler(
|
||||||
Some(category) => {
|
Some(category) => {
|
||||||
let id = category.id;
|
let id = category.id;
|
||||||
mongo_client
|
mongo_client
|
||||||
.set_court_category(&guild_id.to_string(), &id.to_string())
|
.set_court_category(guild_id.into(), id.into())
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
None => return Ok(Response::Simple("Das ist keine Kategorie!".to_owned())),
|
None => return Ok(Response::Simple("Das ist keine Kategorie!".to_owned())),
|
||||||
|
|
@ -277,13 +277,13 @@ struct UserOption;
|
||||||
|
|
||||||
#[nougat::gat]
|
#[nougat::gat]
|
||||||
impl GetOption for UserOption {
|
impl GetOption for UserOption {
|
||||||
type Get<'a> = (&'a User, &'a Option<PartialMember>);
|
type Get<'a> = &'a User;
|
||||||
|
|
||||||
fn extract(
|
fn extract(
|
||||||
command: &ApplicationCommandInteractionDataOptionValue,
|
command: &ApplicationCommandInteractionDataOptionValue,
|
||||||
) -> crate::Result<Self::Get<'_>> {
|
) -> crate::Result<Self::Get<'_>> {
|
||||||
if let ApplicationCommandInteractionDataOptionValue::User(user, member) = command {
|
if let ApplicationCommandInteractionDataOptionValue::User(user, _) = command {
|
||||||
Ok((user, member))
|
Ok(user)
|
||||||
} else {
|
} else {
|
||||||
Err(eyre!("Expected user!"))
|
Err(eyre!("Expected user!"))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serenity::{
|
use serenity::{
|
||||||
http::Http,
|
http::Http,
|
||||||
model::{channel::PermissionOverwriteType, id::ChannelId, prelude::*, Permissions},
|
model::{channel::PermissionOverwriteType, prelude::*, Permissions},
|
||||||
};
|
};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
use crate::{handler::Response, model::CourtRoom, Mongo, WrapErr};
|
use crate::{
|
||||||
|
handler::Response,
|
||||||
|
model::{CourtRoom, SnowflakeId},
|
||||||
|
Mongo, WrapErr,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||||
pub enum LawsuitState {
|
pub enum LawsuitState {
|
||||||
|
|
@ -19,14 +21,14 @@ pub enum LawsuitState {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Lawsuit {
|
pub struct Lawsuit {
|
||||||
pub plaintiff: String,
|
pub plaintiff: SnowflakeId,
|
||||||
pub accused: String,
|
pub accused: SnowflakeId,
|
||||||
pub plaintiff_layer: Option<String>,
|
pub plaintiff_layer: Option<SnowflakeId>,
|
||||||
pub accused_layer: Option<String>,
|
pub accused_layer: Option<SnowflakeId>,
|
||||||
pub judge: String,
|
pub judge: SnowflakeId,
|
||||||
pub reason: String,
|
pub reason: String,
|
||||||
pub state: LawsuitState,
|
pub state: LawsuitState,
|
||||||
pub court_room: Option<String>,
|
pub court_room: Option<SnowflakeId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Lawsuit {
|
impl Lawsuit {
|
||||||
|
|
@ -37,7 +39,7 @@ impl Lawsuit {
|
||||||
mongo_client: &Mongo,
|
mongo_client: &Mongo,
|
||||||
) -> Result<Response> {
|
) -> Result<Response> {
|
||||||
let state = mongo_client
|
let state = mongo_client
|
||||||
.find_or_insert_state(&guild_id.to_string())
|
.find_or_insert_state(guild_id.into())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let free_room = state
|
let free_room = state
|
||||||
|
|
@ -55,7 +57,7 @@ impl Lawsuit {
|
||||||
http,
|
http,
|
||||||
guild_id,
|
guild_id,
|
||||||
state.court_rooms.len(),
|
state.court_rooms.len(),
|
||||||
ChannelId::from_str(category).wrap_err("invalid channel_id stored")?,
|
*category,
|
||||||
mongo_client,
|
mongo_client,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|
@ -83,8 +85,6 @@ impl Lawsuit {
|
||||||
return Ok(response);
|
return Ok(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: now give the people their roles
|
|
||||||
|
|
||||||
Ok(Response::Simple(format!(
|
Ok(Response::Simple(format!(
|
||||||
"ha eine ufgmacht im channel <#{}>",
|
"ha eine ufgmacht im channel <#{}>",
|
||||||
room.channel_id
|
room.channel_id
|
||||||
|
|
@ -104,7 +104,7 @@ impl Lawsuit {
|
||||||
.channels(http)
|
.channels(http)
|
||||||
.await
|
.await
|
||||||
.wrap_err("fetch channels")?;
|
.wrap_err("fetch channels")?;
|
||||||
let channel = channels.get(&ChannelId::from_str(&room.channel_id).expect("oh god"));
|
let channel = channels.get(&room.channel_id.into());
|
||||||
|
|
||||||
match channel {
|
match channel {
|
||||||
Some(channel) => {
|
Some(channel) => {
|
||||||
|
|
@ -155,7 +155,7 @@ async fn create_room(
|
||||||
http: &Http,
|
http: &Http,
|
||||||
guild_id: GuildId,
|
guild_id: GuildId,
|
||||||
room_len: usize,
|
room_len: usize,
|
||||||
category_id: ChannelId,
|
category_id: SnowflakeId,
|
||||||
mongo_client: &Mongo,
|
mongo_client: &Mongo,
|
||||||
) -> Result<Result<CourtRoom, Response>> {
|
) -> Result<Result<CourtRoom, Response>> {
|
||||||
let room_number = room_len + 1;
|
let room_number = room_len + 1;
|
||||||
|
|
@ -184,7 +184,7 @@ async fn create_room(
|
||||||
|
|
||||||
let channel_id = match channels.values().find(|c| c.name() == room_name) {
|
let channel_id = match channels.values().find(|c| c.name() == room_name) {
|
||||||
Some(channel) => {
|
Some(channel) => {
|
||||||
if channel.parent_id != Some(category_id) {
|
if channel.parent_id != Some(category_id.into()) {
|
||||||
return Ok(Err(Response::Simple(format!(
|
return Ok(Err(Response::Simple(format!(
|
||||||
"de channel {room_name} isch i de falsche kategorie, man eh"
|
"de channel {room_name} isch i de falsche kategorie, man eh"
|
||||||
))));
|
))));
|
||||||
|
|
@ -210,13 +210,13 @@ async fn create_room(
|
||||||
};
|
};
|
||||||
|
|
||||||
let room = CourtRoom {
|
let room = CourtRoom {
|
||||||
channel_id: channel_id.to_string(),
|
channel_id: channel_id.into(),
|
||||||
ongoing_lawsuit: false,
|
ongoing_lawsuit: false,
|
||||||
role_id: role_id.to_string(),
|
role_id: role_id.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
mongo_client
|
mongo_client
|
||||||
.add_court_room(&guild_id.to_string(), &room)
|
.add_court_room(guild_id.into(), &room)
|
||||||
.await
|
.await
|
||||||
.wrap_err("add court room to database")?;
|
.wrap_err("add court room to database")?;
|
||||||
|
|
||||||
|
|
|
||||||
98
src/model.rs
98
src/model.rs
|
|
@ -1,28 +1,104 @@
|
||||||
|
use std::{
|
||||||
|
fmt::{Display, Formatter},
|
||||||
|
num::ParseIntError,
|
||||||
|
str::FromStr,
|
||||||
|
};
|
||||||
|
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use mongodb::{
|
use mongodb::{
|
||||||
bson,
|
bson,
|
||||||
bson::doc,
|
bson::{doc, Bson},
|
||||||
options::{ClientOptions, Credential},
|
options::{ClientOptions, Credential},
|
||||||
Client, Collection, Database,
|
Client, Collection, Database,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serenity::model::id::{ChannelId, GuildId, RoleId, UserId};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
use crate::{lawsuit::Lawsuit, WrapErr};
|
use crate::{lawsuit::Lawsuit, WrapErr};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct SnowflakeId(#[serde(with = "serde_string")] pub u64);
|
||||||
|
|
||||||
|
impl FromStr for SnowflakeId {
|
||||||
|
type Err = ParseIntError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||||
|
s.parse().map(Self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for SnowflakeId {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
Display::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod serde_string {
|
||||||
|
use std::{fmt::Display, str::FromStr};
|
||||||
|
|
||||||
|
use serde::{de, Deserialize, Deserializer, Serializer};
|
||||||
|
|
||||||
|
pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
T: Display,
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
serializer.collect_str(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
|
||||||
|
where
|
||||||
|
T: FromStr,
|
||||||
|
T::Err: Display,
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
String::deserialize(deserializer)?
|
||||||
|
.parse()
|
||||||
|
.map_err(de::Error::custom)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SnowflakeId> for Bson {
|
||||||
|
fn from(id: SnowflakeId) -> Self {
|
||||||
|
Bson::String(id.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! from_snowflake {
|
||||||
|
($($ty:ty),*) => {
|
||||||
|
$(
|
||||||
|
impl From<SnowflakeId> for $ty {
|
||||||
|
fn from(id: SnowflakeId) -> Self {
|
||||||
|
Self(id.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<$ty> for SnowflakeId {
|
||||||
|
fn from(id: $ty) -> Self {
|
||||||
|
Self(id.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
from_snowflake!(GuildId, RoleId, ChannelId, UserId);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub guild_id: String,
|
pub guild_id: SnowflakeId,
|
||||||
pub lawsuits: Vec<Lawsuit>,
|
pub lawsuits: Vec<Lawsuit>,
|
||||||
pub court_category: Option<String>,
|
pub court_category: Option<SnowflakeId>,
|
||||||
pub court_rooms: Vec<CourtRoom>,
|
pub court_rooms: Vec<CourtRoom>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct CourtRoom {
|
pub struct CourtRoom {
|
||||||
pub channel_id: String,
|
pub channel_id: SnowflakeId,
|
||||||
pub ongoing_lawsuit: bool,
|
pub ongoing_lawsuit: bool,
|
||||||
pub role_id: String,
|
pub role_id: SnowflakeId,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Mongo {
|
pub struct Mongo {
|
||||||
|
|
@ -53,7 +129,7 @@ impl Mongo {
|
||||||
Ok(Self { db })
|
Ok(Self { db })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn find_or_insert_state(&self, guild_id: &str) -> Result<State> {
|
pub async fn find_or_insert_state(&self, guild_id: SnowflakeId) -> Result<State> {
|
||||||
let coll = self.state_coll();
|
let coll = self.state_coll();
|
||||||
let state = coll
|
let state = coll
|
||||||
.find_one(doc! {"guild_id": &guild_id }, None)
|
.find_one(doc! {"guild_id": &guild_id }, None)
|
||||||
|
|
@ -71,7 +147,7 @@ impl Mongo {
|
||||||
Ok(state)
|
Ok(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn new_state(&self, guild_id: String) -> Result<State> {
|
pub async fn new_state(&self, guild_id: SnowflakeId) -> Result<State> {
|
||||||
let state = State {
|
let state = State {
|
||||||
guild_id,
|
guild_id,
|
||||||
lawsuits: vec![],
|
lawsuits: vec![],
|
||||||
|
|
@ -86,7 +162,11 @@ impl Mongo {
|
||||||
Ok(state)
|
Ok(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_court_category(&self, guild_id: &str, category: &str) -> Result<()> {
|
pub async fn set_court_category(
|
||||||
|
&self,
|
||||||
|
guild_id: SnowflakeId,
|
||||||
|
category: SnowflakeId,
|
||||||
|
) -> Result<()> {
|
||||||
let _ = self.find_or_insert_state(guild_id).await?;
|
let _ = self.find_or_insert_state(guild_id).await?;
|
||||||
let coll = self.state_coll();
|
let coll = self.state_coll();
|
||||||
coll.update_one(
|
coll.update_one(
|
||||||
|
|
@ -99,7 +179,7 @@ impl Mongo {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_court_room(&self, guild_id: &str, room: &CourtRoom) -> Result<()> {
|
pub async fn add_court_room(&self, guild_id: SnowflakeId, room: &CourtRoom) -> Result<()> {
|
||||||
let _ = self.find_or_insert_state(guild_id).await?;
|
let _ = self.find_or_insert_state(guild_id).await?;
|
||||||
let coll = self.state_coll();
|
let coll = self.state_coll();
|
||||||
coll.update_one(
|
coll.update_one(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue