@@ -25,6 +25,8 @@ static ROVER_API_KEY: LazyLock<String> =
2525static DEVFORUM_COOKIE : LazyLock < Option < String > > =
2626 LazyLock :: new ( || std:: env:: var ( "DEVFORUM_COOKIE" ) . ok ( ) ) ;
2727
28+ const DEVFORUM_MEMBER_TRUST_LEVEL : u8 = 1 ; // Trust level for DevForum members
29+
2830#[ async_trait]
2931impl ComponentHandler for VerifyDevForumRank < ' _ > {
3032 fn model ( ) -> anyhow:: Result < Component > {
@@ -45,7 +47,7 @@ impl ComponentHandler for VerifyDevForumRank<'_> {
4547 . await ?
4648 . roles ;
4749
48- // Respond early if the user doesn't have the verified role
50+ // Respond early if the user doesn't have the verified role,
4951 // this is a quick check to avoid unnecessary API calls
5052 if let Some ( r_id) = ctx. cfg . roles . roblox_verified {
5153 if !member_roles. contains ( & r_id) {
@@ -125,17 +127,10 @@ async fn get_response_content(
125127 return "Failed to fetch your DevForum data." . to_string ( ) ;
126128 } ,
127129 } ;
130+ let is_member = devforum_data. user . trust_level >= DEVFORUM_MEMBER_TRUST_LEVEL ;
128131
129132 // Update the user's roles in the Discord server based on their trust level.
130- match update_user_roles (
131- guild_id,
132- author_id,
133- ctx,
134- & devforum_data. user . trust_level ,
135- member_roles,
136- )
137- . await
138- {
133+ match update_user_roles ( guild_id, author_id, ctx, is_member, member_roles) . await {
139134 Ok ( ( ) ) => format ! (
140135 "Successfully updated your roles to match your DevForum trust level: `{}`" ,
141136 devforum_data. user. trust_level
@@ -278,23 +273,31 @@ async fn fetch_devforum_data(
278273/// * `guild_id` - The ID of the Discord server.
279274/// * `user_id` - The ID of the Discord user.
280275/// * `state` - The state of the bot.
281- /// * `trust_level ` - The trust level of the user .
276+ /// * `is_member ` - Whether the user is a DevForum member .
282277async fn update_user_roles (
283278 guild_id : Id < GuildMarker > ,
284279 user_id : Id < UserMarker > ,
285280 state : & crate :: Context ,
286- trust_level : & DevForumTrustLevel ,
281+ is_member : bool ,
287282 mut member_roles : Vec < Id < RoleMarker > > ,
288283) -> anyhow:: Result < ( ) > {
289- let roles = trust_level. roles ( & state. cfg ) ;
290- // Remove the roles that are no longer applicable
291- member_roles. retain ( |role_id| !roles. remove . contains ( role_id) ) ;
292-
293- // Add the role if it is not already present
294- if let Some ( role_id) = roles. add {
295- if !member_roles. contains ( & role_id) {
296- member_roles. push ( role_id) ;
297- }
284+ let member_role_pos = member_roles
285+ . iter ( )
286+ . position ( |& r| r == state. cfg . roles . devforum_member ) ;
287+
288+ match ( is_member, member_role_pos) {
289+ ( true , None ) => {
290+ // If the user is a member but doesn't have the role, add it
291+ member_roles. push ( state. cfg . roles . devforum_member ) ;
292+ } ,
293+ ( false , Some ( pos) ) => {
294+ // If the user is not a member but has the role, remove it
295+ member_roles. remove ( pos) ;
296+ } ,
297+ _ => {
298+ // If the user is a member and has the role, do nothing
299+ return Ok ( ( ) ) ;
300+ } ,
298301 }
299302
300303 // Update the guild member with the new roles
@@ -341,50 +344,10 @@ struct DevForumAPIResponse {
341344
342345#[ derive( Deserialize ) ]
343346struct DevForumUser {
344- trust_level : DevForumTrustLevel ,
345- }
346-
347- #[ derive( Deserialize_repr , Debug ) ]
348- #[ repr( u8 ) ]
349- enum DevForumTrustLevel {
350- Visitor = 0 ,
351- Member = 1 ,
352- Regular = 2 ,
353- Staff ,
347+ trust_level : u8 ,
354348}
355349
356350struct RoleData {
357351 add : Option < Id < RoleMarker > > ,
358- remove : Vec < Id < RoleMarker > > ,
359- }
360-
361- impl DevForumTrustLevel {
362- /// Returns the roles to add and remove based on the trust level.
363- fn roles ( & self , cfg : & crate :: Config ) -> RoleData {
364- match self {
365- DevForumTrustLevel :: Visitor => RoleData {
366- add : None ,
367- remove : vec ! [ cfg. roles. devforum_member, cfg. roles. devforum_regular] ,
368- } ,
369- DevForumTrustLevel :: Member => RoleData {
370- add : Some ( cfg. roles . devforum_member ) ,
371- remove : vec ! [ cfg. roles. devforum_regular] ,
372- } ,
373- DevForumTrustLevel :: Regular | DevForumTrustLevel :: Staff => RoleData {
374- add : Some ( cfg. roles . devforum_regular ) ,
375- remove : vec ! [ cfg. roles. devforum_member] ,
376- } ,
377- }
378- }
379- }
380-
381- impl std:: fmt:: Display for DevForumTrustLevel {
382- fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
383- match self {
384- DevForumTrustLevel :: Visitor => write ! ( f, "Visitor" ) ,
385- DevForumTrustLevel :: Member => write ! ( f, "Member" ) ,
386- DevForumTrustLevel :: Regular => write ! ( f, "Regular" ) ,
387- DevForumTrustLevel :: Staff => write ! ( f, "Staff" ) ,
388- }
389- }
352+ remove : Option < Id < RoleMarker > > ,
390353}
0 commit comments