diff --git a/src/handler.rs b/src/handler.rs index 373f20c..70a9ea8 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -197,11 +197,11 @@ async fn lawsuit_command_handler( UserOption::get_optional(options.get(5)).wrap_err("accused_layer")?; let mut lawsuit = Lawsuit { - plaintiff: plaintiff.id.into(), - accused: accused.id.into(), - judge: judge.id.into(), - plaintiff_layer: plaintiff_layer.map(|user| user.id.into()), - accused_layer: accused_layer.map(|user| user.id.into()), + plaintiff: plaintiff.0.id.into(), + accused: accused.0.id.into(), + judge: judge.0.id.into(), + plaintiff_lawyer: plaintiff_layer.map(|user| user.0.id.into()), + accused_lawyer: accused_layer.map(|user| user.0.id.into()), reason: reason.to_owned(), state: LawsuitState::Initial, court_room: None, @@ -277,13 +277,13 @@ struct UserOption; #[nougat::gat] impl GetOption for UserOption { - type Get<'a> = &'a User; + type Get<'a> = (&'a User, &'a Option); fn extract( command: &ApplicationCommandInteractionDataOptionValue, ) -> crate::Result> { - if let ApplicationCommandInteractionDataOptionValue::User(user, _) = command { - Ok(user) + if let ApplicationCommandInteractionDataOptionValue::User(user, member) = command { + Ok((user, member)) } else { Err(eyre!("Expected user!")) } diff --git a/src/lawsuit.rs b/src/lawsuit.rs index dfb443b..da37207 100644 --- a/src/lawsuit.rs +++ b/src/lawsuit.rs @@ -1,4 +1,5 @@ use color_eyre::Result; +use mongodb::bson::doc; use serde::{Deserialize, Serialize}; use serenity::{ http::Http, @@ -23,8 +24,8 @@ pub enum LawsuitState { pub struct Lawsuit { pub plaintiff: SnowflakeId, pub accused: SnowflakeId, - pub plaintiff_layer: Option, - pub accused_layer: Option, + pub plaintiff_lawyer: Option, + pub accused_lawyer: Option, pub judge: SnowflakeId, pub reason: String, pub state: LawsuitState, @@ -38,9 +39,7 @@ impl Lawsuit { guild_id: GuildId, mongo_client: &Mongo, ) -> Result { - let state = mongo_client - .find_or_insert_state(guild_id.into()) - .await?; + let state = mongo_client.find_or_insert_state(guild_id.into()).await?; let free_room = state .court_rooms @@ -74,7 +73,7 @@ impl Lawsuit { )), }; - self.court_room = Some(room.channel_id.clone()); + self.court_room = Some(room.channel_id); let result = self .send_process_open_message(http, guild_id, &room) @@ -85,6 +84,40 @@ impl Lawsuit { return Ok(response); } + mongo_client.add_lawsuit(guild_id.into(), self).await?; + mongo_client + .set_court_room( + guild_id.into(), + room.channel_id, + doc! { "court_rooms.$.ongoing_lawsuit": true }, + ) + .await?; + + async fn assign_role( + user: SnowflakeId, + http: &Http, + guild_id: GuildId, + role_id: SnowflakeId, + ) -> Result<()> { + let mut member = guild_id.member(http, user).await.wrap_err("fetch member")?; + member + .add_role(http, role_id) + .await + .wrap_err("add role to member")?; + + Ok(()) + } + + assign_role(self.accused, http, guild_id, room.role_id).await?; + if let Some(accused_lawyer) = self.accused_lawyer { + assign_role(accused_lawyer, http, guild_id, room.role_id).await?; + } + assign_role(self.plaintiff, http, guild_id, room.role_id).await?; + if let Some(plaintiff_lawyer) = self.plaintiff_lawyer { + assign_role(plaintiff_lawyer, http, guild_id, room.role_id).await?; + } + assign_role(self.judge, http, guild_id, room.role_id).await?; + Ok(Response::Simple(format!( "ha eine ufgmacht im channel <#{}>", room.channel_id @@ -118,7 +151,7 @@ impl Lawsuit { .field("Kläger", format!("<@{}>", self.plaintiff), false) .field( "Anwalt des Klägers", - match &self.plaintiff_layer { + match &self.plaintiff_lawyer { Some(lawyer) => format!("<@{}>", lawyer), None => "TBD".to_string(), }, @@ -127,7 +160,7 @@ impl Lawsuit { .field("Angeklagter", format!("<@{}>", self.accused), false) .field( "Anwalt des Angeklagten", - match &self.accused_layer { + match &self.accused_lawyer { Some(lawyer) => format!("<@{}>", lawyer), None => "TBD".to_string(), }, diff --git a/src/main.rs b/src/main.rs index 2aa4663..caa8558 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +extern crate core; + mod handler; mod lawsuit; mod model; diff --git a/src/model.rs b/src/model.rs index 649f595..971dd6a 100644 --- a/src/model.rs +++ b/src/model.rs @@ -183,8 +183,8 @@ impl Mongo { let _ = self.find_or_insert_state(guild_id).await?; let coll = self.state_coll(); coll.update_one( - doc! {"guild_id": &guild_id }, - doc! {"$push": { "court_rooms": bson::to_bson(room).wrap_err("invalid bson for room")? }}, + doc! { "guild_id": &guild_id }, + doc! { "$push": { "court_rooms": bson::to_bson(room).wrap_err("invalid bson for room")? }}, None, ) .await @@ -192,6 +192,40 @@ impl Mongo { Ok(()) } + pub async fn add_lawsuit(&self, guild_id: SnowflakeId, lawsuit: &Lawsuit) -> Result<()> { + let _ = self.find_or_insert_state(guild_id).await?; + let coll = self.state_coll(); + + coll.update_one( + doc! { "guild_id": &guild_id }, + doc! { "$push": { "lawsuits": bson::to_bson(lawsuit).wrap_err("invalid bson for lawsuit")? } }, + None, + ) + .await + .wrap_err("push lawsuit")?; + + Ok(()) + } + + pub async fn set_court_room( + &self, + guild_id: SnowflakeId, + channel_id: SnowflakeId, + value: impl Into, + ) -> Result<()> { + let _ = self.find_or_insert_state(guild_id).await?; + let coll = self.state_coll(); + + coll.update_one( + doc! { "guild_id": &guild_id, "court_rooms.channel_id": channel_id }, + doc! { "$set": value.into() }, + None, + ) + .await + .wrap_err("set courtroom")?; + Ok(()) + } + fn state_coll(&self) -> Collection { self.db.collection("state") }