[fractal/fractal-next] power-level: Use a type for PowerLevel



commit a76055b393ff8a52b2451e4183e0a24f803d2ae6
Author: Julian Sparber <julian sparber net>
Date:   Thu Nov 25 12:43:05 2021 +0100

    power-level: Use a type for PowerLevel
    
    Implemented by @V02460

 src/session/room/member.rs       | 15 ++++++++-------
 src/session/room/mod.rs          |  4 +++-
 src/session/room/power_levels.rs | 23 +++++++++++++----------
 3 files changed, 24 insertions(+), 18 deletions(-)
---
diff --git a/src/session/room/member.rs b/src/session/room/member.rs
index 4b7af9fa..65f86027 100644
--- a/src/session/room/member.rs
+++ b/src/session/room/member.rs
@@ -7,6 +7,7 @@ use matrix_sdk::ruma::identifiers::{MxcUri, UserId};
 use matrix_sdk::RoomMember;
 
 use crate::prelude::*;
+use crate::session::room::power_levels::{PowerLevel, POWER_LEVEL_MAX, POWER_LEVEL_MIN};
 use crate::session::{Room, User};
 
 mod imp {
@@ -16,7 +17,7 @@ mod imp {
 
     #[derive(Debug, Default)]
     pub struct Member {
-        pub power_level: Cell<u32>,
+        pub power_level: Cell<PowerLevel>,
     }
 
     #[glib::object_subclass]
@@ -29,12 +30,12 @@ mod imp {
     impl ObjectImpl for Member {
         fn properties() -> &'static [glib::ParamSpec] {
             static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
-                vec![glib::ParamSpec::new_uint(
+                vec![glib::ParamSpec::new_int64(
                     "power-level",
                     "Power level",
                     "Power level of the member in its room.",
-                    0,
-                    100,
+                    POWER_LEVEL_MIN,
+                    POWER_LEVEL_MAX,
                     0,
                     glib::ParamFlags::READABLE | glib::ParamFlags::EXPLICIT_NOTIFY,
                 )]
@@ -64,12 +65,12 @@ impl Member {
             .expect("Failed to create Member")
     }
 
-    pub fn power_level(&self) -> u32 {
+    pub fn power_level(&self) -> PowerLevel {
         let priv_ = imp::Member::from_instance(self);
         priv_.power_level.get()
     }
 
-    fn set_power_level(&self, power_level: u32) {
+    fn set_power_level(&self, power_level: PowerLevel) {
         if self.power_level() == power_level {
             return;
         }
@@ -87,7 +88,7 @@ impl Member {
 
         self.set_display_name(member.display_name().map(String::from));
         self.avatar().set_url(member.avatar_url().cloned());
-        self.set_power_level(member.power_level().clamp(0, 100) as u32);
+        self.set_power_level(member.power_level());
     }
 
     /// Update the user based on the the room member state event
diff --git a/src/session/room/mod.rs b/src/session/room/mod.rs
index a7061c5d..da22f45d 100644
--- a/src/session/room/mod.rs
+++ b/src/session/room/mod.rs
@@ -12,7 +12,9 @@ pub use self::highlight_flags::HighlightFlags;
 pub use self::item::Item;
 pub use self::item::ItemType;
 pub use self::member::Member;
-pub use self::power_levels::{PowerLevels, RoomAction};
+pub use self::power_levels::{
+    PowerLevel, PowerLevels, RoomAction, POWER_LEVEL_MAX, POWER_LEVEL_MIN,
+};
 pub use self::room_type::RoomType;
 pub use self::timeline::Timeline;
 
diff --git a/src/session/room/power_levels.rs b/src/session/room/power_levels.rs
index 1e134798..0d538a75 100644
--- a/src/session/room/power_levels.rs
+++ b/src/session/room/power_levels.rs
@@ -11,6 +11,14 @@ use crate::utils::prop_expr;
 #[gboxed(type_name = "BoxedPowerLevelsEventContent")]
 pub struct BoxedPowerLevelsEventContent(RoomPowerLevelsEventContent);
 
+/// Power level of a user.
+///
+/// Is usually in the range (0..=100), but can be any JS integer.
+pub type PowerLevel = i64;
+// Same value as MAX_SAFE_INT from js_int.
+pub const POWER_LEVEL_MAX: i64 = 0x001F_FFFF_FFFF_FFFF;
+pub const POWER_LEVEL_MIN: i64 = -POWER_LEVEL_MAX;
+
 mod imp {
     use super::*;
     use once_cell::sync::Lazy;
@@ -67,7 +75,7 @@ impl PowerLevels {
     }
 
     /// Returns the power level minimally required to perform the given action.
-    pub fn min_level_for_room_action(&self, room_action: &RoomAction) -> u32 {
+    pub fn min_level_for_room_action(&self, room_action: &RoomAction) -> PowerLevel {
         let priv_ = imp::PowerLevels::from_instance(self);
         let content = priv_.content.borrow();
         min_level_for_room_action(&content.0, room_action)
@@ -77,7 +85,7 @@ impl PowerLevels {
     pub fn new_allowed_expr(&self, member: &Member, room_action: RoomAction) -> gtk::Expression {
         gtk::ClosureExpression::new(
             move |args| {
-                let power_level: u32 = args[1].get().unwrap();
+                let power_level: PowerLevel = args[1].get().unwrap();
                 let content = args[2].get::<BoxedPowerLevelsEventContent>().unwrap().0;
                 power_level >= min_level_for_room_action(&content, &room_action)
             },
@@ -108,8 +116,8 @@ impl Default for PowerLevels {
 fn min_level_for_room_action(
     content: &RoomPowerLevelsEventContent,
     room_action: &RoomAction,
-) -> u32 {
-    let power_level = i64::from(match room_action {
+) -> PowerLevel {
+    match room_action {
         RoomAction::Ban => content.ban,
         RoomAction::Invite => content.invite,
         RoomAction::Kick => content.kick,
@@ -123,13 +131,8 @@ fn min_level_for_room_action(
             .events
             .get(event_type)
             .unwrap_or(&content.events_default),
-    });
-
-    if (0..=100).contains(&power_level) {
-        power_level as u32
-    } else {
-        0
     }
+    .into()
 }
 
 /// Actions that require different power levels to perform them.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]