diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 73a1a928..cdc1d4cb 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -21,7 +21,7 @@ variables:
     - if: '$CI_COMMIT_BRANCH == "next"'
     - if: "$CI_COMMIT_TAG"
   interruptible: true
-  image: "rust:latest"
+  image: "rust:1.56"
   tags: ["docker"]
   variables:
     CARGO_PROFILE_RELEASE_LTO: "true"
diff --git a/Cargo.toml b/Cargo.toml
index 32233305..f335873a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,7 +7,8 @@ homepage = "https://conduit.rs"
 repository = "https://gitlab.com/famedly/conduit"
 readme = "README.md"
 version = "0.2.0"
-edition = "2018"
+rust-version = "1.56"
+edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
diff --git a/Dockerfile b/Dockerfile
index 5812fdf9..b629690d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
 # syntax=docker/dockerfile:1
-FROM docker.io/rust:1.53-alpine AS builder
+FROM docker.io/rust:1.58-alpine AS builder
 WORKDIR /usr/src/conduit
 
 # Install required packages to build Conduit and it's dependencies
@@ -38,7 +38,7 @@ FROM docker.io/alpine:3.15.0 AS runner
 # You still need to map the port when using the docker command or docker-compose.
 EXPOSE 6167
 
-# Note from @jfowl: I would like to remove this in the future and just have the Docker version be configured with envs. 
+# Note from @jfowl: I would like to remove this in the future and just have the Docker version be configured with envs.
 ENV CONDUIT_CONFIG="/srv/conduit/conduit.toml"
 
 # Conduit needs:
@@ -78,4 +78,4 @@ WORKDIR /srv/conduit
 
 # Run Conduit and print backtraces on panics
 ENV RUST_BACKTRACE=1
-ENTRYPOINT [ "/srv/conduit/conduit" ]
\ No newline at end of file
+ENTRYPOINT [ "/srv/conduit/conduit" ]
diff --git a/rust-toolchain b/rust-toolchain
deleted file mode 100644
index 74df8b16..00000000
--- a/rust-toolchain
+++ /dev/null
@@ -1 +0,0 @@
-1.53
diff --git a/src/client_server/context.rs b/src/client_server/context.rs
index 94a44e39..e1177661 100644
--- a/src/client_server/context.rs
+++ b/src/client_server/context.rs
@@ -3,8 +3,7 @@ use ruma::{
     api::client::{error::ErrorKind, r0::context::get_context},
     events::EventType,
 };
-use std::collections::HashSet;
-use std::convert::TryFrom;
+use std::{collections::HashSet, convert::TryFrom};
 
 #[cfg(feature = "conduit_bin")]
 use rocket::get;
@@ -55,8 +54,8 @@ pub async fn get_context_route(
         ))?;
 
     if !db.rooms.lazy_load_was_sent_before(
-        &sender_user,
-        &sender_device,
+        sender_user,
+        sender_device,
         &body.room_id,
         &base_event.sender,
     )? {
@@ -79,8 +78,8 @@ pub async fn get_context_route(
 
     for (_, event) in &events_before {
         if !db.rooms.lazy_load_was_sent_before(
-            &sender_user,
-            &sender_device,
+            sender_user,
+            sender_device,
             &body.room_id,
             &event.sender,
         )? {
@@ -112,8 +111,8 @@ pub async fn get_context_route(
 
     for (_, event) in &events_after {
         if !db.rooms.lazy_load_was_sent_before(
-            &sender_user,
-            &sender_device,
+            sender_user,
+            sender_device,
             &body.room_id,
             &event.sender,
         )? {
diff --git a/src/client_server/keys.rs b/src/client_server/keys.rs
index be0675d8..e7aec26b 100644
--- a/src/client_server/keys.rs
+++ b/src/client_server/keys.rs
@@ -272,7 +272,7 @@ pub async fn get_key_changes_route(
     device_list_updates.extend(
         db.users
             .keys_changed(
-                &sender_user.to_string(),
+                sender_user.as_str(),
                 body.from
                     .parse()
                     .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid `from`."))?,
diff --git a/src/client_server/message.rs b/src/client_server/message.rs
index 36653fab..7d904f90 100644
--- a/src/client_server/message.rs
+++ b/src/client_server/message.rs
@@ -139,7 +139,7 @@ pub async fn get_message_events_route(
     let to = body.to.as_ref().map(|t| t.parse());
 
     db.rooms
-        .lazy_load_confirm_delivery(&sender_user, &sender_device, &body.room_id, from)?;
+        .lazy_load_confirm_delivery(sender_user, sender_device, &body.room_id, from)?;
 
     // Use limit or else 10
     let limit = body.limit.try_into().map_or(10_usize, |l: u32| l as usize);
@@ -168,8 +168,8 @@ pub async fn get_message_events_route(
 
             for (_, event) in &events_after {
                 if !db.rooms.lazy_load_was_sent_before(
-                    &sender_user,
-                    &sender_device,
+                    sender_user,
+                    sender_device,
                     &body.room_id,
                     &event.sender,
                 )? {
@@ -205,8 +205,8 @@ pub async fn get_message_events_route(
 
             for (_, event) in &events_before {
                 if !db.rooms.lazy_load_was_sent_before(
-                    &sender_user,
-                    &sender_device,
+                    sender_user,
+                    sender_device,
                     &body.room_id,
                     &event.sender,
                 )? {
@@ -239,8 +239,8 @@ pub async fn get_message_events_route(
 
     if let Some(next_token) = next_token {
         db.rooms.lazy_load_mark_sent(
-            &sender_user,
-            &sender_device,
+            sender_user,
+            sender_device,
             &body.room_id,
             lazy_loaded,
             next_token,
diff --git a/src/client_server/profile.rs b/src/client_server/profile.rs
index 29b1ae87..71e61da3 100644
--- a/src/client_server/profile.rs
+++ b/src/client_server/profile.rs
@@ -52,7 +52,7 @@ pub async fn set_displayname_route(
                                 .room_state_get(
                                     &room_id,
                                     &EventType::RoomMember,
-                                    &sender_user.to_string(),
+                                    sender_user.as_str(),
                                 )?
                                 .ok_or_else(|| {
                                     Error::bad_database(
@@ -195,7 +195,7 @@ pub async fn set_avatar_url_route(
                                 .room_state_get(
                                     &room_id,
                                     &EventType::RoomMember,
-                                    &sender_user.to_string(),
+                                    sender_user.as_str(),
                                 )?
                                 .ok_or_else(|| {
                                     Error::bad_database(
diff --git a/src/database.rs b/src/database.rs
index 1997dc0a..7a4ddc66 100644
--- a/src/database.rs
+++ b/src/database.rs
@@ -212,28 +212,22 @@ impl Database {
             return Ok(());
         }
 
-        if sled_exists {
-            if config.database_backend != "sled" {
-                return Err(Error::bad_config(
-                    "Found sled at database_path, but is not specified in config.",
-                ));
-            }
+        if sled_exists && config.database_backend != "sled" {
+            return Err(Error::bad_config(
+                "Found sled at database_path, but is not specified in config.",
+            ));
         }
 
-        if sqlite_exists {
-            if config.database_backend != "sqlite" {
-                return Err(Error::bad_config(
-                    "Found sqlite at database_path, but is not specified in config.",
-                ));
-            }
+        if sqlite_exists && config.database_backend != "sqlite" {
+            return Err(Error::bad_config(
+                "Found sqlite at database_path, but is not specified in config.",
+            ));
         }
 
-        if rocksdb_exists {
-            if config.database_backend != "rocksdb" {
-                return Err(Error::bad_config(
-                    "Found rocksdb at database_path, but is not specified in config.",
-                ));
-            }
+        if rocksdb_exists && config.database_backend != "rocksdb" {
+            return Err(Error::bad_config(
+                "Found rocksdb at database_path, but is not specified in config.",
+            ));
         }
 
         Ok(())
diff --git a/src/database/abstraction.rs b/src/database/abstraction.rs
index 17bd971f..321b064f 100644
--- a/src/database/abstraction.rs
+++ b/src/database/abstraction.rs
@@ -23,12 +23,12 @@ pub trait DatabaseEngine: Send + Sync {
     where
         Self: Sized;
     fn open_tree(&self, name: &'static str) -> Result<Arc<dyn Tree>>;
-    fn flush(self: &Self) -> Result<()>;
-    fn cleanup(self: &Self) -> Result<()> {
+    fn flush(&self) -> Result<()>;
+    fn cleanup(&self) -> Result<()> {
         Ok(())
     }
-    fn memory_usage(self: &Self) -> Result<String> {
-        Ok("Current database engine does not support memory usage reporting.".to_string())
+    fn memory_usage(&self) -> Result<String> {
+        Ok("Current database engine does not support memory usage reporting.".to_owned())
     }
 }
 
diff --git a/src/database/admin.rs b/src/database/admin.rs
index 7d2301d9..bf38bd8c 100644
--- a/src/database/admin.rs
+++ b/src/database/admin.rs
@@ -118,7 +118,7 @@ impl Admin {
                                 if let Ok(response) = guard._db.memory_usage() {
                                     send_message(RoomMessageEventContent::text_plain(response), guard, &state_lock);
                                 } else {
-                                    send_message(RoomMessageEventContent::text_plain("Failed to get database memory usage.".to_string()), guard, &state_lock);
+                                    send_message(RoomMessageEventContent::text_plain("Failed to get database memory usage.".to_owned()), guard, &state_lock);
                                 }
                             }
                             AdminCommand::SendMessage(message) => {
diff --git a/src/database/rooms.rs b/src/database/rooms.rs
index 0ba6c9ba..c9a3c202 100644
--- a/src/database/rooms.rs
+++ b/src/database/rooms.rs
@@ -2727,7 +2727,7 @@ impl Rooms {
             let state_lock = mutex_state.lock().await;
 
             let mut event: RoomMemberEventContent = serde_json::from_str(
-                self.room_state_get(room_id, &EventType::RoomMember, &user_id.to_string())?
+                self.room_state_get(room_id, &EventType::RoomMember, user_id.as_str())?
                     .ok_or(Error::BadRequest(
                         ErrorKind::BadState,
                         "Cannot leave a room you are not a member of.",
@@ -3462,8 +3462,7 @@ impl Rooms {
                 &key[0].to_be_bytes(),
                 &chain
                     .iter()
-                    .map(|s| s.to_be_bytes().to_vec())
-                    .flatten()
+                    .flat_map(|s| s.to_be_bytes().to_vec())
                     .collect::<Vec<u8>>(),
             )?;
         }
@@ -3484,11 +3483,11 @@ impl Rooms {
     ) -> Result<bool> {
         let mut key = user_id.as_bytes().to_vec();
         key.push(0xff);
-        key.extend_from_slice(&device_id.as_bytes());
+        key.extend_from_slice(device_id.as_bytes());
         key.push(0xff);
-        key.extend_from_slice(&room_id.as_bytes());
+        key.extend_from_slice(room_id.as_bytes());
         key.push(0xff);
-        key.extend_from_slice(&ll_user.as_bytes());
+        key.extend_from_slice(ll_user.as_bytes());
         Ok(self.lazyloadedids.get(&key)?.is_some())
     }
 
@@ -3528,14 +3527,14 @@ impl Rooms {
         )) {
             let mut prefix = user_id.as_bytes().to_vec();
             prefix.push(0xff);
-            prefix.extend_from_slice(&device_id.as_bytes());
+            prefix.extend_from_slice(device_id.as_bytes());
             prefix.push(0xff);
-            prefix.extend_from_slice(&room_id.as_bytes());
+            prefix.extend_from_slice(room_id.as_bytes());
             prefix.push(0xff);
 
             for ll_id in user_ids {
                 let mut key = prefix.clone();
-                key.extend_from_slice(&ll_id.as_bytes());
+                key.extend_from_slice(ll_id.as_bytes());
                 self.lazyloadedids.insert(&key, &[])?;
             }
         }
@@ -3546,15 +3545,15 @@ impl Rooms {
     #[tracing::instrument(skip(self))]
     pub fn lazy_load_reset(
         &self,
-        user_id: &Box<UserId>,
-        device_id: &Box<DeviceId>,
-        room_id: &Box<RoomId>,
+        user_id: &UserId,
+        device_id: &DeviceId,
+        room_id: &RoomId,
     ) -> Result<()> {
         let mut prefix = user_id.as_bytes().to_vec();
         prefix.push(0xff);
-        prefix.extend_from_slice(&device_id.as_bytes());
+        prefix.extend_from_slice(device_id.as_bytes());
         prefix.push(0xff);
-        prefix.extend_from_slice(&room_id.as_bytes());
+        prefix.extend_from_slice(room_id.as_bytes());
         prefix.push(0xff);
 
         for (key, _) in self.lazyloadedids.scan_prefix(prefix) {
diff --git a/src/database/uiaa.rs b/src/database/uiaa.rs
index 5e11467e..b0c8d6dd 100644
--- a/src/database/uiaa.rs
+++ b/src/database/uiaa.rs
@@ -166,13 +166,12 @@ impl Uiaa {
         user_id: &UserId,
         device_id: &DeviceId,
         session: &str,
-    ) -> Result<Option<CanonicalJsonValue>> {
-        Ok(self
-            .userdevicesessionid_uiaarequest
+    ) -> Option<CanonicalJsonValue> {
+        self.userdevicesessionid_uiaarequest
             .read()
             .unwrap()
             .get(&(user_id.to_owned(), device_id.to_owned(), session.to_owned()))
-            .map(|j| j.to_owned()))
+            .map(|j| j.to_owned())
     }
 
     fn update_uiaa_session(
diff --git a/src/database/users.rs b/src/database/users.rs
index c4fcee3d..69a277c6 100644
--- a/src/database/users.rs
+++ b/src/database/users.rs
@@ -531,11 +531,11 @@ impl Users {
         prefix.push(0xff);
 
         // Master key
-        let master_key_map = master_key
+        let mut master_key_ids = master_key
             .deserialize()
             .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid master key"))?
-            .keys;
-        let mut master_key_ids = master_key_map.values();
+            .keys
+            .into_values();
 
         let master_key_id = master_key_ids.next().ok_or(Error::BadRequest(
             ErrorKind::InvalidParam,
@@ -560,13 +560,14 @@ impl Users {
 
         // Self-signing key
         if let Some(self_signing_key) = self_signing_key {
-            let self_signing_key_map = self_signing_key
+            let mut self_signing_key_ids = self_signing_key
                 .deserialize()
                 .map_err(|_| {
                     Error::BadRequest(ErrorKind::InvalidParam, "Invalid self signing key")
                 })?
-                .keys;
-            let mut self_signing_key_ids = self_signing_key_map.values();
+                .keys
+                .into_values();
+
             let self_signing_key_id = self_signing_key_ids.next().ok_or(Error::BadRequest(
                 ErrorKind::InvalidParam,
                 "Self signing key contained no key.",
@@ -593,13 +594,14 @@ impl Users {
 
         // User-signing key
         if let Some(user_signing_key) = user_signing_key {
-            let user_signing_key_map = user_signing_key
+            let mut user_signing_key_ids = user_signing_key
                 .deserialize()
                 .map_err(|_| {
                     Error::BadRequest(ErrorKind::InvalidParam, "Invalid user signing key")
                 })?
-                .keys;
-            let mut user_signing_key_ids = user_signing_key_map.values();
+                .keys
+                .into_values();
+
             let user_signing_key_id = user_signing_key_ids.next().ok_or(Error::BadRequest(
                 ErrorKind::InvalidParam,
                 "User signing key contained no key.",
diff --git a/src/lib.rs b/src/lib.rs
index 82b8f340..745eb394 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -7,21 +7,23 @@
 #![allow(clippy::suspicious_else_formatting)]
 #![deny(clippy::dbg_macro)]
 
-pub mod appservice_server;
-pub mod client_server;
+use std::ops::Deref;
+
 mod database;
 mod error;
 mod pdu;
 mod ruma_wrapper;
-pub mod server_server;
 mod utils;
 
+pub mod appservice_server;
+pub mod client_server;
+pub mod server_server;
+
 pub use database::{Config, Database};
 pub use error::{Error, Result};
 pub use pdu::PduEvent;
 pub use rocket::Config as RocketConfig;
 pub use ruma_wrapper::{ConduitResult, Ruma, RumaResponse};
-use std::ops::Deref;
 
 pub struct State<'r, T: Send + Sync + 'static>(pub &'r T);
 
diff --git a/src/main.rs b/src/main.rs
index 56faa3e7..d9bbc240 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,27 +7,9 @@
 #![allow(clippy::suspicious_else_formatting)]
 #![deny(clippy::dbg_macro)]
 
-pub mod appservice_server;
-pub mod client_server;
-pub mod server_server;
-
-mod database;
-mod error;
-mod pdu;
-mod ruma_wrapper;
-mod utils;
-
 use std::sync::Arc;
 
-use database::Config;
-pub use database::Database;
-pub use error::{Error, Result};
 use opentelemetry::trace::{FutureExt, Tracer};
-pub use pdu::PduEvent;
-pub use rocket::State;
-use ruma::api::client::error::ErrorKind;
-pub use ruma_wrapper::{ConduitResult, Ruma, RumaResponse};
-
 use rocket::{
     catch, catchers,
     figment::{
@@ -36,9 +18,13 @@ use rocket::{
     },
     routes, Request,
 };
+use ruma::api::client::error::ErrorKind;
 use tokio::sync::RwLock;
 use tracing_subscriber::{prelude::*, EnvFilter};
 
+pub use conduit::*; // Re-export everything from the library crate
+pub use rocket::State;
+
 fn setup_rocket(config: Figment, data: Arc<RwLock<Database>>) -> rocket::Rocket<rocket::Build> {
     rocket::custom(config)
         .manage(data)
diff --git a/src/ruma_wrapper.rs b/src/ruma_wrapper.rs
index 4b8d5dea..1bd921d9 100644
--- a/src/ruma_wrapper.rs
+++ b/src/ruma_wrapper.rs
@@ -296,14 +296,11 @@ where
                 .and_then(|auth| auth.get("session"))
                 .and_then(|session| session.as_str())
                 .and_then(|session| {
-                    db.uiaa
-                        .get_uiaa_request(
-                            &user_id,
-                            &sender_device.clone().unwrap_or_else(|| "".into()),
-                            session,
-                        )
-                        .ok()
-                        .flatten()
+                    db.uiaa.get_uiaa_request(
+                        &user_id,
+                        &sender_device.clone().unwrap_or_else(|| "".into()),
+                        session,
+                    )
                 })
             {
                 for (key, value) in initial_request {
diff --git a/src/server_server.rs b/src/server_server.rs
index 54ae0251..9129951b 100644
--- a/src/server_server.rs
+++ b/src/server_server.rs
@@ -1938,7 +1938,7 @@ pub(crate) fn fetch_and_handle_outliers<'a>(
                 match handle_outlier_pdu(
                     origin,
                     create_event,
-                    &next_id,
+                    next_id,
                     room_id,
                     value.clone(),
                     db,
@@ -2358,7 +2358,7 @@ pub fn get_event_route(
     let room_id = <&RoomId>::try_from(room_id_str)
         .map_err(|_| Error::bad_database("Invalid room id field in event in database"))?;
 
-    if !db.rooms.server_in_room(sender_servername, &room_id)? {
+    if !db.rooms.server_in_room(sender_servername, room_id)? {
         return Err(Error::BadRequest(
             ErrorKind::Forbidden,
             "Server is not in room",
@@ -2821,7 +2821,7 @@ async fn create_join_event(
         ));
     }
 
-    acl_check(sender_servername, room_id, &db)?;
+    acl_check(sender_servername, room_id, db)?;
 
     // We need to return the state prior to joining, let's keep a reference to that here
     let shortstatehash = db