From b2efbd8a331e9464cde600cc2e1e7346b0b9d6f3 Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Tue, 14 Dec 2021 23:00:41 +0100
Subject: [PATCH] Parsing commands + use &str instead of String

The &str type should be lighter than String.
---
 src/cmd/mod.rs     | 16 +++++++--------
 src/cmd/package.rs |  4 ++--
 src/matrix.rs      | 49 +++++++++++++++++++++++-----------------------
 3 files changed, 35 insertions(+), 34 deletions(-)

diff --git a/src/cmd/mod.rs b/src/cmd/mod.rs
index 6512419..6c44b15 100644
--- a/src/cmd/mod.rs
+++ b/src/cmd/mod.rs
@@ -7,9 +7,9 @@ use std::{process::abort, string::String, sync::Arc};
 #[allow(dead_code)]
 #[derive(Clone)]
 enum CmdHandler {
-    Simple(Arc<dyn Fn(Vec<String>) -> bool>),
-    Echo(Arc<dyn Fn(Vec<String>) -> String>),
-    MultiEcho(Arc<dyn Fn(Vec<String>) -> Vec<String>>),
+    Simple(Arc<dyn Fn(Vec<&str>) -> bool>),
+    Echo(Arc<dyn Fn(Vec<&str>) -> String>),
+    MultiEcho(Arc<dyn Fn(Vec<&str>) -> Vec<String>>),
 }
 
 #[allow(dead_code)]
@@ -25,12 +25,12 @@ unsafe impl Send for Cmd {}
 
 impl Cmd {
     #[allow(dead_code)]
-    pub fn matches(&self, name: &String, args: &Vec<String>) -> bool {
+    pub fn matches(&self, name: &str, args: &Vec<&str>) -> bool {
         (self.name == *name) && (self.argc as usize == args.len())
     }
 
     #[allow(dead_code)]
-    pub fn exec(&self, args: Vec<String>) -> String {
+    pub fn exec(&self, args: Vec<&str>) -> String {
         if args.len() != self.argc as usize {
             error!("Arg count doesn't match");
             abort();
@@ -52,7 +52,7 @@ impl Cmd {
     }
 
     #[allow(dead_code)]
-    pub fn new_simple(name: String, argc: u32, f: Arc<dyn Fn(Vec<String>) -> bool>) -> Cmd {
+    pub fn new_simple(name: String, argc: u32, f: Arc<dyn Fn(Vec<&str>) -> bool>) -> Cmd {
         Cmd {
             name: name,
             argc: argc,
@@ -61,7 +61,7 @@ impl Cmd {
     }
 
     #[allow(dead_code)]
-    pub fn new_echo(name: String, argc: u32, f: Arc<dyn Fn(Vec<String>) -> String>) -> Cmd {
+    pub fn new_echo(name: String, argc: u32, f: Arc<dyn Fn(Vec<&str>) -> String>) -> Cmd {
         Cmd {
             name: name,
             argc: argc,
@@ -73,7 +73,7 @@ impl Cmd {
     pub fn new_multi_echo(
         name: String,
         argc: u32,
-        f: Arc<dyn Fn(Vec<String>) -> Vec<String>>,
+        f: Arc<dyn Fn(Vec<&str>) -> Vec<String>>,
     ) -> Cmd {
         Cmd {
             name: name,
diff --git a/src/cmd/package.rs b/src/cmd/package.rs
index 097e4a1..20cb0d6 100644
--- a/src/cmd/package.rs
+++ b/src/cmd/package.rs
@@ -17,7 +17,7 @@ pub struct CmdPackage {
 
 impl CmdPackage {
     #[allow(dead_code)]
-    pub fn has_command(&self, user_cmd: &Vec<String>) -> bool {
+    pub fn has_command(&self, user_cmd: &Vec<&str>) -> bool {
         match user_cmd.split_first() {
             None => false,
             Some((name, args)) => match self
@@ -32,7 +32,7 @@ impl CmdPackage {
     }
 
     #[allow(dead_code)]
-    pub fn handle(&self, room: &JoinedRoom, user_id: &UserId, user_cmd: Vec<String>) -> String {
+    pub fn handle(&self, room: &JoinedRoom, user_id: &UserId, user_cmd: Vec<&str>) -> String {
         match CmdAcl::action_permited(&self.admin_register, &self.acl, room, user_id) {
             Err(string) => "Action not permited: ".to_string() + &string,
             Ok(()) => match user_cmd.split_first() {
diff --git a/src/matrix.rs b/src/matrix.rs
index 030ccb6..bbacd2a 100644
--- a/src/matrix.rs
+++ b/src/matrix.rs
@@ -98,25 +98,24 @@ pub async fn connect_and_handle(config: Config) -> Result<()> {
 
     GLOBAL_PKG.lock().unwrap().push(pkg);
 
-    let on_msg_room_event =
-        move |ev: SyncMessageEvent<MessageEventContent>,
-              room: Room,
-              _encryption_info: Option<EncryptionInfo>| async move {
-            let sender_id = ev.sender;
-            if sender_id.as_str() == room.own_user_id().as_str() {
-                return;
-            }
+    let on_msg_room_event = |ev: SyncMessageEvent<MessageEventContent>,
+                             room: Room,
+                             _encryption_info: Option<EncryptionInfo>| async {
+        let sender_id = ev.sender;
+        if sender_id.as_str() == room.own_user_id().as_str() {
+            return ();
+        }
 
-            if room.name().is_none() {
-                warn!("Unsupported rooms without names");
-                return;
-            }
+        if room.name().is_none() {
+            warn!("Unsupported rooms without names");
+            return ();
+        }
 
-            if let Room::Joined(joined) = room {
-                if let MessageType::Text(TextMessageEventContent { body, .. }) = ev.content.msgtype
-                {
-                    if body.starts_with("%") {
-                        let args = vec![];
+        if let Room::Joined(joined) = room {
+            if let MessageType::Text(TextMessageEventContent { body, .. }) = ev.content.msgtype {
+                if body.starts_with("%") {
+                    if let Some(stripped) = body.strip_prefix("%") {
+                        let args = stripped.split(' ').collect::<Vec<&str>>();
                         let mut res: String = format!("Command not found");
                         if let Some(pkg) = GLOBAL_PKG
                             .lock()
@@ -139,15 +138,17 @@ pub async fn connect_and_handle(config: Config) -> Result<()> {
                     }
                 }
             }
+        }
 
-            // if let Room::Invited(_) = room {
-            //     warn!("Bot was invited by {sender_id} to room {room_id} a.k.a. {room_name}",);
-            // }
+        // if let Room::Invited(_) = room {
+        //     warn!("Bot was invited by {sender_id} to room {room_id} a.k.a. {room_name}",);
+        // }
 
-            // if let Room::Left(_) = room {
-            //     error!("Bot left room {room_id} a.k.a. {room_name}")
-            // }
-        };
+        // if let Room::Left(_) = room {
+        //     error!("Bot left room {room_id} a.k.a. {room_name}")
+        // }
+        return ();
+    };
 
     let alice = UserId::try_from(config.user_name)?;
     let client = Client::new(config.homeserver_url)?;
-- 
GitLab