From f39bc07bb952adba2407587106892bc4ff7584eb Mon Sep 17 00:00:00 2001
From: Paul Makles <paulmakles@gmail.com>
Date: Wed, 30 Dec 2020 11:36:32 +0000
Subject: [PATCH] Start work on notifications from client, cargo fmt

---
 src/database/entities/channel.rs        | 26 ++++++---
 src/database/entities/mod.rs            |  4 +-
 src/database/entities/user.rs           | 27 +++++----
 src/database/guards/mod.rs              |  2 +-
 src/database/guards/reference.rs        | 25 +++++----
 src/database/guards/user.rs             |  1 +
 src/database/migrations/init.rs         | 54 +++++++++---------
 src/database/migrations/scripts.rs      | 49 +++++++++--------
 src/database/mod.rs                     |  4 +-
 src/database/permissions/mod.rs         |  6 +-
 src/main.rs                             | 13 +++--
 src/notifications/events.rs             |  7 +--
 src/notifications/hive.rs               |  6 +-
 src/notifications/mod.rs                |  2 +-
 src/notifications/websocket.rs          | 73 ++++++++++++++++---------
 src/routes/channels/mod.rs              |  2 +-
 src/routes/guild/mod.rs                 |  2 +-
 src/routes/mod.rs                       |  6 +-
 src/routes/onboard/complete.rs          | 50 ++++++++++-------
 src/routes/onboard/hello.rs             |  2 +-
 src/routes/onboard/mod.rs               |  7 +--
 src/routes/root.rs                      |  2 +-
 src/routes/users/add_friend.rs          | 24 ++++++--
 src/routes/users/block_user.rs          | 39 ++++++++-----
 src/routes/users/fetch_dms.rs           | 19 ++++---
 src/routes/users/fetch_relationship.rs  |  6 +-
 src/routes/users/fetch_relationships.rs | 14 ++---
 src/routes/users/fetch_user.rs          |  4 +-
 src/routes/users/mod.rs                 | 14 ++---
 src/routes/users/open_dm.rs             | 19 +++----
 src/routes/users/remove_friend.rs       | 28 ++++++----
 src/routes/users/unblock_user.rs        | 41 ++++++++------
 src/util/mod.rs                         |  2 +-
 src/util/result.rs                      | 15 +++--
 34 files changed, 336 insertions(+), 259 deletions(-)

diff --git a/src/database/entities/channel.rs b/src/database/entities/channel.rs
index 37736dc..ad10efc 100644
--- a/src/database/entities/channel.rs
+++ b/src/database/entities/channel.rs
@@ -1,6 +1,9 @@
-use serde::{Deserialize, Serialize};
-use crate::{database::get_collection, util::result::{Error, Result}};
+use crate::{
+    database::get_collection,
+    util::result::{Error, Result},
+};
 use mongodb::bson::to_document;
+use serde::{Deserialize, Serialize};
 
 /*#[derive(Serialize, Deserialize, Debug, Clone)]
 pub struct LastMessage {
@@ -38,7 +41,7 @@ pub enum Channel {
     SavedMessages {
         #[serde(rename = "_id")]
         id: String,
-        user: String
+        user: String,
     },
     DirectMessage {
         #[serde(rename = "_id")]
@@ -53,20 +56,25 @@ pub enum Channel {
         owner: String,
         description: String,
         recipients: Vec<String>,
-    }
+    },
 }
 
 impl Channel {
     pub async fn save(&self) -> Result<()> {
         get_collection("channels")
             .insert_one(
-                to_document(&self)
-                    .map_err(|_| Error::DatabaseError { operation: "to_bson", with: "channel" })?,
-                None
+                to_document(&self).map_err(|_| Error::DatabaseError {
+                    operation: "to_bson",
+                    with: "channel",
+                })?,
+                None,
             )
             .await
-            .map_err(|_| Error::DatabaseError { operation: "insert_one", with: "channel" })?;
-        
+            .map_err(|_| Error::DatabaseError {
+                operation: "insert_one",
+                with: "channel",
+            })?;
+
         Ok(())
     }
 }
diff --git a/src/database/entities/mod.rs b/src/database/entities/mod.rs
index 02c0f5e..d64512a 100644
--- a/src/database/entities/mod.rs
+++ b/src/database/entities/mod.rs
@@ -1,9 +1,9 @@
 mod channel;
-mod message;
 mod guild;
+mod message;
 mod user;
 
 pub use channel::*;
-pub use message::*;
 pub use guild::*;
+pub use message::*;
 pub use user::*;
diff --git a/src/database/entities/user.rs b/src/database/entities/user.rs
index c6aca1f..1d97b7f 100644
--- a/src/database/entities/user.rs
+++ b/src/database/entities/user.rs
@@ -1,10 +1,10 @@
+use crate::database::get_collection;
+use crate::database::guards::reference::Ref;
 use mongodb::bson::{doc, from_bson, Bson};
 use rauth::auth::Session;
 use rocket::http::Status;
-use serde::{Deserialize, Serialize};
-use crate::database::guards::reference::Ref;
-use crate::database::get_collection;
 use rocket::request::{self, FromRequest, Outcome, Request};
+use serde::{Deserialize, Serialize};
 
 #[derive(Serialize, Deserialize, Debug, Clone)]
 pub enum RelationshipStatus {
@@ -14,7 +14,7 @@ pub enum RelationshipStatus {
     Outgoing,
     Incoming,
     Blocked,
-    BlockedOther
+    BlockedOther,
 }
 
 #[derive(Serialize, Deserialize, Debug)]
@@ -44,24 +44,29 @@ impl<'a, 'r> FromRequest<'a, 'r> for User {
             .find_one(
                 doc! {
                     "_id": &session.user_id
-                }, None
+                },
+                None,
             )
-            .await {
+            .await
+        {
             if let Some(doc) = result {
-                Outcome::Success(
-                    from_bson(Bson::Document(doc)).unwrap()
-                )
+                Outcome::Success(from_bson(Bson::Document(doc)).unwrap())
             } else {
                 Outcome::Failure((Status::Forbidden, rauth::util::Error::InvalidSession))
             }
         } else {
-            Outcome::Failure((Status::InternalServerError, rauth::util::Error::DatabaseError))
+            Outcome::Failure((
+                Status::InternalServerError,
+                rauth::util::Error::DatabaseError,
+            ))
         }
     }
 }
 
 impl User {
     pub fn as_ref(&self) -> Ref {
-        Ref { id: self.id.to_string() }
+        Ref {
+            id: self.id.to_string(),
+        }
     }
 }
diff --git a/src/database/guards/mod.rs b/src/database/guards/mod.rs
index 728ede5..339d4c8 100644
--- a/src/database/guards/mod.rs
+++ b/src/database/guards/mod.rs
@@ -1,5 +1,5 @@
-pub mod user;
 pub mod reference;
+pub mod user;
 
 /*
 // ! FIXME
diff --git a/src/database/guards/reference.rs b/src/database/guards/reference.rs
index 851bb2f..6504638 100644
--- a/src/database/guards/reference.rs
+++ b/src/database/guards/reference.rs
@@ -1,10 +1,10 @@
-use mongodb::bson::{doc, from_bson, Bson};
-use crate::util::result::{Error, Result};
-use serde::{Deserialize, Serialize};
-use crate::database::get_collection;
 use crate::database::entities::*;
-use rocket::request::FromParam;
+use crate::database::get_collection;
+use crate::util::result::{Error, Result};
+use mongodb::bson::{doc, from_bson, Bson};
 use rocket::http::RawStr;
+use rocket::request::FromParam;
+use serde::{Deserialize, Serialize};
 use validator::Validate;
 
 #[derive(Validate, Serialize, Deserialize)]
@@ -24,15 +24,20 @@ impl Ref {
                 doc! {
                     "_id": &self.id
                 },
-                None
+                None,
             )
             .await
-            .map_err(|_| Error::DatabaseError { operation: "find_one", with: "user" })?
+            .map_err(|_| Error::DatabaseError {
+                operation: "find_one",
+                with: "user",
+            })?
             .ok_or_else(|| Error::UnknownUser)?;
-        
+
         Ok(
-            from_bson(Bson::Document(doc))
-                .map_err(|_| Error::DatabaseError { operation: "from_bson", with: "user" })?
+            from_bson(Bson::Document(doc)).map_err(|_| Error::DatabaseError {
+                operation: "from_bson",
+                with: "user",
+            })?,
         )
     }
 }
diff --git a/src/database/guards/user.rs b/src/database/guards/user.rs
index e69de29..8b13789 100644
--- a/src/database/guards/user.rs
+++ b/src/database/guards/user.rs
@@ -0,0 +1 @@
+
diff --git a/src/database/migrations/init.rs b/src/database/migrations/init.rs
index 4edb04f..e8b2b89 100644
--- a/src/database/migrations/init.rs
+++ b/src/database/migrations/init.rs
@@ -10,28 +10,28 @@ pub async fn create_database() {
     let db = get_db();
 
     db.create_collection("users", None)
-    .await
-    .expect("Failed to create users collection.");
-    
+        .await
+        .expect("Failed to create users collection.");
+
     db.create_collection("channels", None)
-    .await
-    .expect("Failed to create channels collection.");
-    
+        .await
+        .expect("Failed to create channels collection.");
+
     db.create_collection("guilds", None)
-    .await
-    .expect("Failed to create guilds collection.");
-    
+        .await
+        .expect("Failed to create guilds collection.");
+
     db.create_collection("members", None)
-    .await
-    .expect("Failed to create members collection.");
-    
+        .await
+        .expect("Failed to create members collection.");
+
     db.create_collection("messages", None)
-    .await
-    .expect("Failed to create messages collection.");
-    
+        .await
+        .expect("Failed to create messages collection.");
+
     db.create_collection("migrations", None)
-    .await
-    .expect("Failed to create migrations collection.");
+        .await
+        .expect("Failed to create migrations collection.");
 
     db.create_collection(
         "pubsub",
@@ -60,21 +60,21 @@ pub async fn create_database() {
                 }
             ]
         },
-        None
+        None,
     )
     .await
     .expect("Failed to create username index.");
 
     db.collection("migrations")
-    .insert_one(
-        doc! {
-            "_id": 0,
-            "revision": LATEST_REVISION
-        },
-        None,
-    )
-    .await
-    .expect("Failed to save migration info.");
+        .insert_one(
+            doc! {
+                "_id": 0,
+                "revision": LATEST_REVISION
+            },
+            None,
+        )
+        .await
+        .expect("Failed to save migration info.");
 
     info!("Created database.");
 }
diff --git a/src/database/migrations/scripts.rs b/src/database/migrations/scripts.rs
index 5d469ff..5172416 100644
--- a/src/database/migrations/scripts.rs
+++ b/src/database/migrations/scripts.rs
@@ -1,10 +1,10 @@
-use super::super::{get_db, get_collection};
+use super::super::{get_collection, get_db};
 
+use crate::rocket::futures::StreamExt;
 use log::info;
+use mongodb::bson::{doc, from_bson, Bson};
 use mongodb::options::FindOptions;
 use serde::{Deserialize, Serialize};
-use crate::rocket::futures::StreamExt;
-use mongodb::bson::{doc, from_bson, Bson};
 
 #[derive(Serialize, Deserialize)]
 struct MigrationInfo {
@@ -86,7 +86,7 @@ pub async fn run_migrations(revision: i32) -> i32 {
                 .get_str("_id")
                 .expect("Failed to get channel id.")
                 .to_string();
-            
+
             let gid = channel
                 .get_str("guild")
                 .expect("Failed to get guild id.")
@@ -124,27 +124,28 @@ pub async fn run_migrations(revision: i32) -> i32 {
     if revision <= 2 {
         info!("Running migration [revision 2]: Add username index to users.");
 
-        get_db().run_command(
-            doc! {
-                "createIndexes": "users",
-                "indexes": [
-                    {
-                        "key": {
-                            "username": 1
-                        },
-                        "name": "username",
-                        "unique": true,
-                        "collation": {
-                            "locale": "en",
-                            "strength": 2
+        get_db()
+            .run_command(
+                doc! {
+                    "createIndexes": "users",
+                    "indexes": [
+                        {
+                            "key": {
+                                "username": 1
+                            },
+                            "name": "username",
+                            "unique": true,
+                            "collation": {
+                                "locale": "en",
+                                "strength": 2
+                            }
                         }
-                    }
-                ]
-            },
-            None
-        )
-        .await
-        .expect("Failed to create username index.");
+                    ]
+                },
+                None,
+            )
+            .await
+            .expect("Failed to create username index.");
     }
 
     // Reminder to update LATEST_REVISION when adding new migrations.
diff --git a/src/database/mod.rs b/src/database/mod.rs
index 48d81d9..9feb7c8 100644
--- a/src/database/mod.rs
+++ b/src/database/mod.rs
@@ -26,7 +26,7 @@ pub fn get_collection(collection: &str) -> Collection {
     get_db().collection(collection)
 }
 
-pub mod permissions;
-pub mod migrations;
 pub mod entities;
 pub mod guards;
+pub mod migrations;
+pub mod permissions;
diff --git a/src/database/permissions/mod.rs b/src/database/permissions/mod.rs
index f2346a5..01e8386 100644
--- a/src/database/permissions/mod.rs
+++ b/src/database/permissions/mod.rs
@@ -7,7 +7,7 @@ use std::ops;
 pub enum UserPermission {
     Access = 1,
     SendMessage = 2,
-    Invite = 4
+    Invite = 4,
 }
 
 bitfield! {
@@ -40,9 +40,7 @@ pub fn get_relationship(a: &User, b: &Ref) -> RelationshipStatus {
     }
 
     if let Some(relations) = &a.relations {
-        if let Some(relationship) = relations
-            .iter()
-            .find(|x| x.id == b.id) {
+        if let Some(relationship) = relations.iter().find(|x| x.id == b.id) {
             return relationship.status.clone();
         }
     }
diff --git a/src/main.rs b/src/main.rs
index f20e9f4..8c55f5b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -13,15 +13,15 @@ extern crate impl_ops;
 extern crate bitfield;
 extern crate ctrlc;
 
-pub mod notifications;
 pub mod database;
+pub mod notifications;
 pub mod routes;
 pub mod util;
 
-use rauth;
-use log::info;
-use futures::join;
 use async_std::task;
+use futures::join;
+use log::info;
+use rauth;
 use rocket_cors::AllowedOrigins;
 
 fn main() {
@@ -41,7 +41,8 @@ async fn entry() {
     ctrlc::set_handler(move || {
         // Force ungraceful exit to avoid hang.
         std::process::exit(0);
-    }).expect("Error setting Ctrl-C handler");
+    })
+    .expect("Error setting Ctrl-C handler");
 
     join!(
         launch_web(),
@@ -57,7 +58,7 @@ async fn launch_web() {
     }
     .to_cors()
     .expect("Failed to create CORS.");
-    
+
     let auth = rauth::auth::Auth::new(database::get_collection("accounts"));
 
     routes::mount(rauth::routes::mount(rocket::ignite(), "/auth", auth))
diff --git a/src/notifications/events.rs b/src/notifications/events.rs
index 8814ada..b046737 100644
--- a/src/notifications/events.rs
+++ b/src/notifications/events.rs
@@ -1,5 +1,5 @@
-use serde::{Deserialize, Serialize};
 use rauth::auth::Session;
+use serde::{Deserialize, Serialize};
 use snafu::Snafu;
 
 #[derive(Serialize, Deserialize, Debug, Snafu)]
@@ -15,7 +15,7 @@ pub enum WebSocketError {
 #[derive(Deserialize, Debug)]
 #[serde(tag = "type")]
 pub enum ServerboundNotification {
-    Authenticate(Session)
+    Authenticate(Session),
 }
 
 #[derive(Serialize, Deserialize, Debug)]
@@ -78,10 +78,9 @@ pub enum ClientboundNotification {
     GuildDelete {
         id: String,
     },*/
-
     UserRelationship {
         id: String,
         user: String,
         status: i32,
-    }
+    },
 }
diff --git a/src/notifications/hive.rs b/src/notifications/hive.rs
index ec23101..98c8e4b 100644
--- a/src/notifications/hive.rs
+++ b/src/notifications/hive.rs
@@ -1,12 +1,12 @@
 use super::events::ClientboundNotification;
 use crate::database::get_collection;
 
+use futures::FutureExt;
 use hive_pubsub::backend::mongo::MongodbPubSub;
 use hive_pubsub::PubSub;
+use log::{debug, error};
 use once_cell::sync::OnceCell;
 use serde_json::to_string;
-use futures::FutureExt;
-use log::{error, debug};
 
 static HIVE: OnceCell<MongodbPubSub<String, String, ClientboundNotification>> = OnceCell::new();
 
@@ -35,7 +35,7 @@ pub async fn listen() {
         .fuse()
         .await
         .expect("Hive hit an error");
-    
+
     dbg!("a");
 }
 
diff --git a/src/notifications/mod.rs b/src/notifications/mod.rs
index 0312f43..23abbfd 100644
--- a/src/notifications/mod.rs
+++ b/src/notifications/mod.rs
@@ -1,3 +1,3 @@
-pub mod websocket;
 pub mod events;
 pub mod hive;
+pub mod websocket;
diff --git a/src/notifications/websocket.rs b/src/notifications/websocket.rs
index 1b1593a..9d884fb 100644
--- a/src/notifications/websocket.rs
+++ b/src/notifications/websocket.rs
@@ -1,21 +1,26 @@
-use crate::util::variables::WS_HOST;
+use crate::{database::entities::User, util::variables::WS_HOST};
 
-use log::info;
-use ulid::Ulid;
+use async_std::net::{TcpListener, TcpStream};
 use async_std::task;
-use futures::prelude::*;
-use std::str::from_utf8;
-use std::sync::{Arc, RwLock};
+use async_tungstenite::tungstenite::Message;
+use futures::channel::mpsc::{unbounded, UnboundedSender};
+use futures::{pin_mut, prelude::*};
+use log::info;
 use many_to_many::ManyToMany;
+use rauth::auth::Session;
 use std::collections::HashMap;
-use futures::stream::SplitSink;
-use async_tungstenite::WebSocketStream;
-use async_tungstenite::tungstenite::Message;
-use async_std::net::{TcpListener, TcpStream};
+use std::net::SocketAddr;
+use std::str::from_utf8;
+use std::sync::{Arc, Mutex, RwLock};
+use ulid::Ulid;
+
+use super::events::ServerboundNotification;
+
+type Tx = UnboundedSender<Message>;
+type PeerMap = Arc<Mutex<HashMap<SocketAddr, Tx>>>;
 
 lazy_static! {
-    static ref CONNECTIONS: Arc<RwLock<HashMap<String, SplitSink<WebSocketStream<TcpStream>, Message>>>> =
-        Arc::new(RwLock::new(HashMap::new()));
+    static ref CONNECTIONS: PeerMap = Arc::new(Mutex::new(HashMap::new()));
     static ref USERS: Arc<RwLock<ManyToMany<String, String>>> =
         Arc::new(RwLock::new(ManyToMany::new()));
 }
@@ -31,27 +36,41 @@ pub async fn launch_server() {
 }
 
 async fn accept(stream: TcpStream) {
-    let addr = stream.peer_addr().expect("Connected streams should have a peer address.");
+    let addr = stream
+        .peer_addr()
+        .expect("Connected streams should have a peer address.");
     let ws_stream = async_tungstenite::accept_async(stream)
         .await
         .expect("Error during websocket handshake.");
 
-    info!("User established WebSocket connection from {}.", addr);
+    info!("User established WebSocket connection from {}.", &addr);
 
     let id = Ulid::new().to_string();
     let (write, read) = ws_stream.split();
 
-    CONNECTIONS
-        .write()
-        .unwrap()
-        .insert(id, write);
-
-    read
-        .for_each(|message| async {
-            let data = message.unwrap().into_data();
-            // if you mess with the data, you get the bazooki
-            let string = from_utf8(&data).unwrap();
-            println!("{}", string);
-        })
-        .await;
+    let (tx, rx) = unbounded();
+    CONNECTIONS.lock().unwrap().insert(addr, tx);
+
+    let session: Option<Session> = None;
+    let user: Option<User> = None;
+
+    let fwd = rx.map(Ok).forward(write);
+    let reading = read.for_each(|message| async {
+        let data = message.unwrap().into_data();
+        // if you mess with the data, you get the bazooki
+        let string = from_utf8(&data).unwrap();
+
+        if let Ok(notification) = serde_json::from_str::<ServerboundNotification>(string) {
+            match notification {
+                ServerboundNotification::Authenticate(a) => {
+                    dbg!(a);
+                }
+            }
+        }
+    });
+
+    pin_mut!(fwd, reading);
+    future::select(fwd, reading).await;
+
+    println!("User {} disconnected.", &addr);
 }
diff --git a/src/routes/channels/mod.rs b/src/routes/channels/mod.rs
index 9a5378a..018a956 100644
--- a/src/routes/channels/mod.rs
+++ b/src/routes/channels/mod.rs
@@ -1,5 +1,5 @@
 use rocket::Route;
 
 pub fn routes() -> Vec<Route> {
-    routes! []
+    routes![]
 }
diff --git a/src/routes/guild/mod.rs b/src/routes/guild/mod.rs
index 9a5378a..018a956 100644
--- a/src/routes/guild/mod.rs
+++ b/src/routes/guild/mod.rs
@@ -1,5 +1,5 @@
 use rocket::Route;
 
 pub fn routes() -> Vec<Route> {
-    routes! []
+    routes![]
 }
diff --git a/src/routes/mod.rs b/src/routes/mod.rs
index 2789410..77ea709 100644
--- a/src/routes/mod.rs
+++ b/src/routes/mod.rs
@@ -2,11 +2,11 @@ pub use rocket::http::Status;
 pub use rocket::response::Redirect;
 use rocket::Rocket;
 
-mod root;
-mod users;
+mod channels;
 mod guild;
 mod onboard;
-mod channels;
+mod root;
+mod users;
 
 pub fn mount(rocket: Rocket) -> Rocket {
     rocket
diff --git a/src/routes/onboard/complete.rs b/src/routes/onboard/complete.rs
index 1ff0de0..857d7c6 100644
--- a/src/routes/onboard/complete.rs
+++ b/src/routes/onboard/complete.rs
@@ -1,13 +1,13 @@
-use mongodb::options::{Collation, FindOneOptions};
-use crate::util::result::{Error, Result};
-use serde::{Deserialize, Serialize};
 use crate::database::entities::User;
 use crate::database::get_collection;
-use rocket_contrib::json::Json;
-use rauth::auth::Session;
-use validator::Validate;
+use crate::util::result::{Error, Result};
 use mongodb::bson::doc;
+use mongodb::options::{Collation, FindOneOptions};
+use rauth::auth::Session;
 use regex::Regex;
+use rocket_contrib::json::Json;
+use serde::{Deserialize, Serialize};
+use validator::Validate;
 
 lazy_static! {
     static ref RE_USERNAME: Regex = Regex::new(r"^[a-zA-Z0-9-_]+$").unwrap();
@@ -16,7 +16,7 @@ lazy_static! {
 #[derive(Validate, Serialize, Deserialize)]
 pub struct Data {
     #[validate(length(min = 2, max = 32), regex = "RE_USERNAME")]
-    username: String
+    username: String,
 }
 
 #[post("/complete", data = "<data>")]
@@ -24,22 +24,27 @@ pub async fn req(session: Session, user: Option<User>, data: Json<Data>) -> Resu
     if user.is_some() {
         Err(Error::AlreadyOnboarded)?
     }
-    
+
     data.validate()
         .map_err(|error| Error::FailedValidation { error })?;
 
     let col = get_collection("users");
-    if col.find_one(
-        doc! {
-            "username": &data.username
-        },
-        FindOneOptions::builder()
-            .collation(Collation::builder().locale("en").strength(2).build())
-            .build()
-    )
-    .await
-    .map_err(|_| Error::DatabaseError { operation: "find_one", with: "user" })?
-    .is_some() {
+    if col
+        .find_one(
+            doc! {
+                "username": &data.username
+            },
+            FindOneOptions::builder()
+                .collation(Collation::builder().locale("en").strength(2).build())
+                .build(),
+        )
+        .await
+        .map_err(|_| Error::DatabaseError {
+            operation: "find_one",
+            with: "user",
+        })?
+        .is_some()
+    {
         Err(Error::UsernameTaken)?
     }
 
@@ -48,10 +53,13 @@ pub async fn req(session: Session, user: Option<User>, data: Json<Data>) -> Resu
             "_id": session.user_id,
             "username": &data.username
         },
-        None
+        None,
     )
     .await
-    .map_err(|_| Error::DatabaseError { operation: "insert_one", with: "user" })?;
+    .map_err(|_| Error::DatabaseError {
+        operation: "insert_one",
+        with: "user",
+    })?;
 
     Ok(())
 }
diff --git a/src/routes/onboard/hello.rs b/src/routes/onboard/hello.rs
index 8f8f77d..39f112a 100644
--- a/src/routes/onboard/hello.rs
+++ b/src/routes/onboard/hello.rs
@@ -1,6 +1,6 @@
-use rocket_contrib::json::JsonValue;
 use crate::database::entities::User;
 use rauth::auth::Session;
+use rocket_contrib::json::JsonValue;
 
 #[get("/hello")]
 pub async fn req(_session: Session, user: Option<User>) -> JsonValue {
diff --git a/src/routes/onboard/mod.rs b/src/routes/onboard/mod.rs
index c7e9971..727886d 100644
--- a/src/routes/onboard/mod.rs
+++ b/src/routes/onboard/mod.rs
@@ -1,11 +1,8 @@
 use rocket::Route;
 
-mod hello;
 mod complete;
+mod hello;
 
 pub fn routes() -> Vec<Route> {
-    routes! [
-        hello::req,
-        complete::req
-    ]
+    routes![hello::req, complete::req]
 }
diff --git a/src/routes/root.rs b/src/routes/root.rs
index e3f9fc7..52a99d8 100644
--- a/src/routes/root.rs
+++ b/src/routes/root.rs
@@ -1,7 +1,7 @@
 use crate::util::variables::{DISABLE_REGISTRATION, HCAPTCHA_SITEKEY, USE_EMAIL, USE_HCAPTCHA};
 
-use rocket_contrib::json::JsonValue;
 use mongodb::bson::doc;
+use rocket_contrib::json::JsonValue;
 
 #[get("/")]
 pub async fn root() -> JsonValue {
diff --git a/src/routes/users/add_friend.rs b/src/routes/users/add_friend.rs
index d0e1a6a..a0762f2 100644
--- a/src/routes/users/add_friend.rs
+++ b/src/routes/users/add_friend.rs
@@ -1,8 +1,16 @@
-use crate::{database::{entities::{User, RelationshipStatus}, get_collection, guards::reference::Ref, permissions::get_relationship}, util::result::Error};
-use rocket_contrib::json::JsonValue;
 use crate::util::result::Result;
-use mongodb::bson::doc;
+use crate::{
+    database::{
+        entities::{RelationshipStatus, User},
+        get_collection,
+        guards::reference::Ref,
+        permissions::get_relationship,
+    },
+    util::result::Error,
+};
 use futures::try_join;
+use mongodb::bson::doc;
+use rocket_contrib::json::JsonValue;
 
 #[put("/<target>/friend")]
 pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
@@ -42,7 +50,10 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
                 )
             ) {
                 Ok(_) => Ok(json!({ "status": "Friend" })),
-                Err(_) => Err(Error::DatabaseError { operation: "update_one", with: "user" })
+                Err(_) => Err(Error::DatabaseError {
+                    operation: "update_one",
+                    with: "user",
+                }),
             }
         }
         RelationshipStatus::None => {
@@ -77,7 +88,10 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
                 )
             ) {
                 Ok(_) => Ok(json!({ "status": "Outgoing" })),
-                Err(_) => Err(Error::DatabaseError { operation: "update_one", with: "user" })
+                Err(_) => Err(Error::DatabaseError {
+                    operation: "update_one",
+                    with: "user",
+                }),
             }
         }
     }
diff --git a/src/routes/users/block_user.rs b/src/routes/users/block_user.rs
index 59ccd4e..e7f1266 100644
--- a/src/routes/users/block_user.rs
+++ b/src/routes/users/block_user.rs
@@ -1,16 +1,18 @@
-use crate::{database::entities::RelationshipStatus, database::guards::reference::Ref, database::entities::User, database::permissions::get_relationship, util::result::Error, database::get_collection};
-use rocket_contrib::json::JsonValue;
 use crate::util::result::Result;
-use mongodb::bson::doc;
+use crate::{
+    database::entities::RelationshipStatus, database::entities::User, database::get_collection,
+    database::guards::reference::Ref, database::permissions::get_relationship, util::result::Error,
+};
 use futures::try_join;
+use mongodb::bson::doc;
+use rocket_contrib::json::JsonValue;
 
 #[put("/<target>/block")]
 pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
     let col = get_collection("users");
 
     match get_relationship(&user, &target) {
-        RelationshipStatus::User |
-        RelationshipStatus::Blocked => Err(Error::NoEffect),
+        RelationshipStatus::User | RelationshipStatus::Blocked => Err(Error::NoEffect),
         RelationshipStatus::BlockedOther => {
             col.update_one(
                 doc! {
@@ -22,13 +24,16 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
                         "relations.$.status": "Blocked"
                     }
                 },
-                None
+                None,
             )
             .await
-            .map_err(|_| Error::DatabaseError { operation: "update_one", with: "user" })?;
+            .map_err(|_| Error::DatabaseError {
+                operation: "update_one",
+                with: "user",
+            })?;
 
             Ok(json!({ "status": "Blocked" }))
-        },
+        }
         RelationshipStatus::None => {
             match try_join!(
                 col.update_one(
@@ -61,12 +66,15 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
                 )
             ) {
                 Ok(_) => Ok(json!({ "status": "Blocked" })),
-                Err(_) => Err(Error::DatabaseError { operation: "update_one", with: "user" })
+                Err(_) => Err(Error::DatabaseError {
+                    operation: "update_one",
+                    with: "user",
+                }),
             }
-        },
-        RelationshipStatus::Friend |
-        RelationshipStatus::Incoming |
-        RelationshipStatus::Outgoing => {
+        }
+        RelationshipStatus::Friend
+        | RelationshipStatus::Incoming
+        | RelationshipStatus::Outgoing => {
             match try_join!(
                 col.update_one(
                     doc! {
@@ -94,7 +102,10 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
                 )
             ) {
                 Ok(_) => Ok(json!({ "status": "Blocked" })),
-                Err(_) => Err(Error::DatabaseError { operation: "update_one", with: "user" })
+                Err(_) => Err(Error::DatabaseError {
+                    operation: "update_one",
+                    with: "user",
+                }),
             }
         }
     }
diff --git a/src/routes/users/fetch_dms.rs b/src/routes/users/fetch_dms.rs
index 2eda25e..218efae 100644
--- a/src/routes/users/fetch_dms.rs
+++ b/src/routes/users/fetch_dms.rs
@@ -1,9 +1,9 @@
 use crate::database::entities::{Channel, User};
-use mongodb::bson::{Bson, doc, from_bson};
-use crate::util::result::{Error, Result};
 use crate::database::get_collection;
-use rocket_contrib::json::JsonValue;
+use crate::util::result::{Error, Result};
 use futures::StreamExt;
+use mongodb::bson::{doc, from_bson, Bson};
+use rocket_contrib::json::JsonValue;
 
 #[get("/dms")]
 pub async fn req(user: User) -> Result<JsonValue> {
@@ -21,11 +21,14 @@ pub async fn req(user: User) -> Result<JsonValue> {
                 ],
                 "recipients": user.id
             },
-            None
+            None,
         )
         .await
-        .map_err(|_| Error::DatabaseError { operation: "find", with: "channels" })?;
-    
+        .map_err(|_| Error::DatabaseError {
+            operation: "find",
+            with: "channels",
+        })?;
+
     let mut channels = vec![];
     while let Some(result) = cursor.next().await {
         if let Ok(doc) = result {
@@ -33,7 +36,5 @@ pub async fn req(user: User) -> Result<JsonValue> {
         }
     }
 
-    Ok(json!(
-        channels
-    ))
+    Ok(json!(channels))
 }
diff --git a/src/routes/users/fetch_relationship.rs b/src/routes/users/fetch_relationship.rs
index 3c2c686..bd3c0cb 100644
--- a/src/routes/users/fetch_relationship.rs
+++ b/src/routes/users/fetch_relationship.rs
@@ -1,10 +1,8 @@
 use crate::database::{entities::User, guards::reference::Ref, permissions::get_relationship};
-use rocket_contrib::json::JsonValue;
 use crate::util::result::Result;
+use rocket_contrib::json::JsonValue;
 
 #[get("/<target>/relationship")]
 pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
-    Ok(json!({
-        "status": get_relationship(&user, &target)
-    }))
+    Ok(json!({ "status": get_relationship(&user, &target) }))
 }
diff --git a/src/routes/users/fetch_relationships.rs b/src/routes/users/fetch_relationships.rs
index c974244..7df7e7c 100644
--- a/src/routes/users/fetch_relationships.rs
+++ b/src/routes/users/fetch_relationships.rs
@@ -1,14 +1,12 @@
 use crate::database::entities::User;
-use rocket_contrib::json::JsonValue;
 use crate::util::result::Result;
+use rocket_contrib::json::JsonValue;
 
 #[get("/relationships")]
 pub async fn req(user: User) -> Result<JsonValue> {
-    Ok(
-        if let Some(vec) = user.relations {
-            json!(vec)
-        } else {
-            json!([])
-        }
-    )
+    Ok(if let Some(vec) = user.relations {
+        json!(vec)
+    } else {
+        json!([])
+    })
 }
diff --git a/src/routes/users/fetch_user.rs b/src/routes/users/fetch_user.rs
index ec7a23f..acbbfde 100644
--- a/src/routes/users/fetch_user.rs
+++ b/src/routes/users/fetch_user.rs
@@ -1,6 +1,6 @@
+use crate::database::entities::User;
 use crate::database::guards::reference::Ref;
 use crate::util::result::{Error, Result};
-use crate::database::entities::User;
 use rocket_contrib::json::JsonValue;
 
 #[get("/<target>")]
@@ -13,7 +13,7 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
         if !perm.get_access() {
             Err(Error::LabelMe)?
         }
-        
+
         // Only return user relationships if the target is the caller.
         target.relations = None;
     }
diff --git a/src/routes/users/mod.rs b/src/routes/users/mod.rs
index 4a3e004..8f7b4ec 100644
--- a/src/routes/users/mod.rs
+++ b/src/routes/users/mod.rs
@@ -1,24 +1,22 @@
 use rocket::Route;
 
-mod fetch_user;
+mod add_friend;
+mod block_user;
 mod fetch_dms;
-mod open_dm;
-mod fetch_relationships;
 mod fetch_relationship;
-mod add_friend;
+mod fetch_relationships;
+mod fetch_user;
+mod open_dm;
 mod remove_friend;
-mod block_user;
 mod unblock_user;
 
 pub fn routes() -> Vec<Route> {
-    routes! [
+    routes![
         // User Information
         fetch_user::req,
-
         // Direct Messaging
         fetch_dms::req,
         open_dm::req,
-
         // Relationships
         fetch_relationships::req,
         fetch_relationship::req,
diff --git a/src/routes/users/open_dm.rs b/src/routes/users/open_dm.rs
index 32f7496..1136e44 100644
--- a/src/routes/users/open_dm.rs
+++ b/src/routes/users/open_dm.rs
@@ -1,9 +1,9 @@
 use crate::database::entities::{Channel, User};
+use crate::database::get_collection;
 use crate::database::guards::reference::Ref;
 use crate::util::result::{Error, Result};
-use crate::database::get_collection;
-use rocket_contrib::json::JsonValue;
 use mongodb::bson::doc;
+use rocket_contrib::json::JsonValue;
 use ulid::Ulid;
 
 #[get("/<target>/dm")]
@@ -25,25 +25,22 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
     let existing_channel = get_collection("channels")
         .find_one(query, None)
         .await
-        .map_err(|_| Error::DatabaseError { operation: "find_one", with: "channel" })?;
+        .map_err(|_| Error::DatabaseError {
+            operation: "find_one",
+            with: "channel",
+        })?;
 
     if let Some(doc) = existing_channel {
         Ok(json!(doc))
     } else {
         let id = Ulid::new().to_string();
         let channel = if user.id == target.id {
-            Channel::SavedMessages {
-                id,
-                user: user.id
-            }
+            Channel::SavedMessages { id, user: user.id }
         } else {
             Channel::DirectMessage {
                 id,
                 active: false,
-                recipients: vec! [
-                    user.id,
-                    target.id
-                ]
+                recipients: vec![user.id, target.id],
             }
         };
 
diff --git a/src/routes/users/remove_friend.rs b/src/routes/users/remove_friend.rs
index 97290ce..468a6be 100644
--- a/src/routes/users/remove_friend.rs
+++ b/src/routes/users/remove_friend.rs
@@ -1,21 +1,24 @@
-use crate::{database::entities::RelationshipStatus, database::guards::reference::Ref, database::entities::User, database::permissions::get_relationship, util::result::Error, database::get_collection};
-use rocket_contrib::json::JsonValue;
 use crate::util::result::Result;
-use mongodb::bson::doc;
+use crate::{
+    database::entities::RelationshipStatus, database::entities::User, database::get_collection,
+    database::guards::reference::Ref, database::permissions::get_relationship, util::result::Error,
+};
 use futures::try_join;
+use mongodb::bson::doc;
+use rocket_contrib::json::JsonValue;
 
 #[delete("/<target>/friend")]
 pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
     let col = get_collection("users");
 
     match get_relationship(&user, &target) {
-        RelationshipStatus::Blocked |
-        RelationshipStatus::BlockedOther |
-        RelationshipStatus::User |
-        RelationshipStatus::None => Err(Error::NoEffect),
-        RelationshipStatus::Friend |
-        RelationshipStatus::Outgoing |
-        RelationshipStatus::Incoming => {
+        RelationshipStatus::Blocked
+        | RelationshipStatus::BlockedOther
+        | RelationshipStatus::User
+        | RelationshipStatus::None => Err(Error::NoEffect),
+        RelationshipStatus::Friend
+        | RelationshipStatus::Outgoing
+        | RelationshipStatus::Incoming => {
             match try_join!(
                 col.update_one(
                     doc! {
@@ -45,7 +48,10 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
                 )
             ) {
                 Ok(_) => Ok(json!({ "status": "None" })),
-                Err(_) => Err(Error::DatabaseError { operation: "update_one", with: "user" })
+                Err(_) => Err(Error::DatabaseError {
+                    operation: "update_one",
+                    with: "user",
+                }),
             }
         }
     }
diff --git a/src/routes/users/unblock_user.rs b/src/routes/users/unblock_user.rs
index 10e13b6..585170f 100644
--- a/src/routes/users/unblock_user.rs
+++ b/src/routes/users/unblock_user.rs
@@ -1,20 +1,23 @@
-use crate::{database::entities::RelationshipStatus, database::guards::reference::Ref, database::entities::User, database::permissions::get_relationship, util::result::Error, database::get_collection};
-use rocket_contrib::json::JsonValue;
 use crate::util::result::Result;
-use mongodb::bson::doc;
+use crate::{
+    database::entities::RelationshipStatus, database::entities::User, database::get_collection,
+    database::guards::reference::Ref, database::permissions::get_relationship, util::result::Error,
+};
 use futures::try_join;
+use mongodb::bson::doc;
+use rocket_contrib::json::JsonValue;
 
 #[delete("/<target>/block")]
 pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
     let col = get_collection("users");
 
     match get_relationship(&user, &target) {
-        RelationshipStatus::None |
-        RelationshipStatus::User |
-        RelationshipStatus::BlockedOther |
-        RelationshipStatus::Incoming |
-        RelationshipStatus::Outgoing |
-        RelationshipStatus::Friend => Err(Error::NoEffect),
+        RelationshipStatus::None
+        | RelationshipStatus::User
+        | RelationshipStatus::BlockedOther
+        | RelationshipStatus::Incoming
+        | RelationshipStatus::Outgoing
+        | RelationshipStatus::Friend => Err(Error::NoEffect),
         RelationshipStatus::Blocked => {
             match get_relationship(&target.fetch_user().await?, &user.as_ref()) {
                 RelationshipStatus::Blocked => {
@@ -28,13 +31,16 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
                                 "relations.$.status": "BlockedOther"
                             }
                         },
-                        None
+                        None,
                     )
                     .await
-                    .map_err(|_| Error::DatabaseError { operation: "update_one", with: "user" })?;
-        
+                    .map_err(|_| Error::DatabaseError {
+                        operation: "update_one",
+                        with: "user",
+                    })?;
+
                     Ok(json!({ "status": "BlockedOther" }))
-                },
+                }
                 RelationshipStatus::BlockedOther => {
                     match try_join!(
                         col.update_one(
@@ -65,10 +71,13 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
                         )
                     ) {
                         Ok(_) => Ok(json!({ "status": "None" })),
-                        Err(_) => Err(Error::DatabaseError { operation: "update_one", with: "user" })
+                        Err(_) => Err(Error::DatabaseError {
+                            operation: "update_one",
+                            with: "user",
+                        }),
                     }
-                },
-                _ => Err(Error::InternalError)
+                }
+                _ => Err(Error::InternalError),
             }
         }
     }
diff --git a/src/util/mod.rs b/src/util/mod.rs
index 2a4d04f..28c9041 100644
--- a/src/util/mod.rs
+++ b/src/util/mod.rs
@@ -2,9 +2,9 @@ use rand::{distributions::Alphanumeric, Rng};
 use std::collections::HashSet;
 use std::iter::FromIterator;
 
+pub mod captcha;
 pub mod email;
 pub mod result;
-pub mod captcha;
 pub mod variables;
 
 pub fn vec_to_set<T: Clone + Eq + std::hash::Hash>(data: &[T]) -> HashSet<T> {
diff --git a/src/util/result.rs b/src/util/result.rs
index 7f98081..e707f60 100644
--- a/src/util/result.rs
+++ b/src/util/result.rs
@@ -1,11 +1,11 @@
-use rocket::response::{self, Responder, Response};
+use json;
 use rocket::http::{ContentType, Status};
-use validator::ValidationErrors;
 use rocket::request::Request;
+use rocket::response::{self, Responder, Response};
 use serde::Serialize;
-use std::io::Cursor;
 use snafu::Snafu;
-use json;
+use std::io::Cursor;
+use validator::ValidationErrors;
 
 #[derive(Serialize, Debug, Snafu)]
 #[serde(tag = "type")]
@@ -16,7 +16,7 @@ pub enum Error {
     // ? Onboarding related errors.
     #[snafu(display("Already finished onboarding."))]
     AlreadyOnboarded,
-    
+
     // ? User related errors.
     #[snafu(display("Username has already been taken."))]
     UsernameTaken,
@@ -35,7 +35,10 @@ pub enum Error {
     #[snafu(display("Failed to validate fields."))]
     FailedValidation { error: ValidationErrors },
     #[snafu(display("Encountered a database error."))]
-    DatabaseError { operation: &'static str, with: &'static str },
+    DatabaseError {
+        operation: &'static str,
+        with: &'static str,
+    },
     #[snafu(display("Internal server error."))]
     InternalError,
     #[snafu(display("This request had no effect."))]
-- 
GitLab