diff --git a/src/broadcaster.rs b/src/broadcaster.rs
index 5082e5847a90cd3617212298d600114c2ca48bc9..72f148cbc4d37b4d18b4d371ae78f197932ac33a 100644
--- a/src/broadcaster.rs
+++ b/src/broadcaster.rs
@@ -60,7 +60,7 @@ impl Broadcaster {
 
     fn remove_stale_clients(&mut self) {
         let mut ok_clients = Vec::new();
-        for client in self.clients.iter() {
+        for client in &self.clients {
             let result = client.clone().try_send(Bytes::from("data: ping\n\n"));
 
             if let Ok(()) = result {
@@ -73,7 +73,7 @@ impl Broadcaster {
     pub fn new_client(&mut self) -> Client {
         let (tx, rx) = channel(100);
 
-        tx.clone()
+        tx
             .try_send(Bytes::from("data: connected\n\n"))
             .unwrap();
 
@@ -84,7 +84,7 @@ impl Broadcaster {
     pub fn send(&self, event: &str, msg: &str) {
         let msg = Bytes::from(["event:", event, "\n", "data: ", msg, "\n\n"].concat());
 
-        for client in self.clients.iter() {
+        for client in &self.clients {
             client.clone().try_send(msg.clone()).unwrap_or(());
         }
     }
diff --git a/src/import_contest.rs b/src/import_contest.rs
index bbeac6228aba2fc3ef4dd38de86548b1e47e7c19..ddc42ff281de239c4798dbdff98ccca47845577c 100644
--- a/src/import_contest.rs
+++ b/src/import_contest.rs
@@ -368,9 +368,11 @@ fn read_string_from_zip_by_name<R: Read + Seek>(
 pub use xml::contest::Contest;
 pub use xml::problem::Problem;
 
+pub type ContestProblemsZipReport<R> = (Contest, Vec<(String, Problem)>, ZipArchive<R>, String);
+
 pub fn import_file<R: Read + Seek>(
     reader: R,
-) -> Result<(Contest, Vec<(String, Problem)>, ZipArchive<R>, String), ImportContestError> {
+) -> Result<ContestProblemsZipReport<R>, ImportContestError> {
     let mut report = String::new();
 
     let mut zip = ZipArchive::new(reader)?;
@@ -389,7 +391,7 @@ pub fn import_file<R: Read + Seek>(
     for name in zip
         .file_names()
         .filter(|name| PROBLEM_XML_PATH_REGEX.is_match(name))
-        .map(|s| s.into())
+        .map(std::convert::Into::into)
         .collect::<Vec<String>>()
     {
         println!("{}", name);
@@ -400,7 +402,7 @@ pub fn import_file<R: Read + Seek>(
         report.push_str("\n---\n");
         report.push_str(&read_string_from_zip_by_name(&mut zip, &name)?);
         report.push_str("---\n");
-        report.push_str("\n");
+        report.push('\n');
 
         problems.push((
             PROBLEM_XML_PATH_REGEX
@@ -417,13 +419,13 @@ pub fn import_file<R: Read + Seek>(
     Ok((contest, problems, zip, report))
 }
 
-pub fn format_width(pattern_path: &String, i: usize) -> String {
+#[must_use] pub fn format_width(pattern_path: &str, i: usize) -> String {
     lazy_static! {
         static ref WIDTH_REGEX: Regex = Regex::new(r"%0(\d)+d").unwrap();
     }
     WIDTH_REGEX
         .replace(pattern_path, |caps: &Captures| {
-            return format!("{:0width$}", i, width = caps[1].parse().unwrap());
+            format!("{:0width$}", i, width = caps[1].parse().unwrap())
         })
         .into()
 }
diff --git a/src/main.rs b/src/main.rs
index efbbbc092e0744e23ef0fb4eb8173aa193da51e3..1d4a5216ed1ae37670400b89bc879a4e3798e57e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -98,11 +98,11 @@ fn create_job_from_submission(submission: Submission, metadata: ProblemByContest
         memory_limit_kib: metadata.memory_limit_bytes / 1_024,
 
         which: Some(job::Which::Judgement(job::Judgement {
-            source_text: submission.source_text.into(),
+            source_text: submission.source_text,
             test_count: metadata.test_count,
-            test_pattern: format!("./{}/{}", metadata.id, metadata.test_pattern).into(),
+            test_pattern: format!("./{}/{}", metadata.id, metadata.test_pattern),
             checker_language: metadata.checker_language,
-            checker_source_path: format!("./{}/{}", metadata.id, metadata.checker_path).into(),
+            checker_source_path: format!("./{}/{}", metadata.id, metadata.checker_path),
         })),
     }
 }
@@ -172,7 +172,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
             .app_data(Data::new(job_sender_data.clone()))
             .app_data(Data::new(job_result_sender_data.clone()))
             .app_data(Data::new(languages_data.clone()))
-            .app_data(Data::new(tz.clone()))
+            .app_data(Data::new(tz))
             .wrap(ErrorHandlers::new().handler(http::StatusCode::UNAUTHORIZED, pages::render_401))
             .wrap(ErrorHandlers::new().handler(http::StatusCode::BAD_REQUEST, pages::render_400))
             .wrap(
@@ -237,7 +237,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
     let update_dabase_sender = job_result_sender.clone();
     log::info!("Starting at {}", addr);
     tokio::try_join!(
-        server.run().map_err(|e| Into::<Box<dyn Error>>::into(e)),
+        server.run().map_err(Into::<Box<dyn Error>>::into),
         Server::builder()
             .add_service(JobQueueServer::new(JobQueuer {
                 job_receiver,
@@ -245,12 +245,10 @@ async fn main() -> Result<(), Box<dyn Error>> {
                 languages,
             }))
             .serve(addr)
-            .map_err(|e| Into::<Box<dyn Error>>::into(e)),
-        update_database(update_dabase_sender.subscribe(), pool.clone()).map_err(|e| Into::<
+            .map_err(Into::<Box<dyn Error>>::into),
+        update_database(update_dabase_sender.subscribe(), pool.clone()).map_err(Into::<
             Box<dyn Error>,
-        >::into(
-            e
-        ))
+        >::into)
     )?;
 
     Ok(())
diff --git a/src/models/submission.rs b/src/models/submission.rs
index ac095c5d0eb2b546491bc2a1a6566017d03970b1..5ecad3644972fb7d10d7d510aa56bbec253f3c41 100644
--- a/src/models/submission.rs
+++ b/src/models/submission.rs
@@ -24,6 +24,7 @@ pub struct Submission {
     pub failed_test: Option<i32>,
 }
 
+#[allow(clippy::type_complexity)]
 const SUBMISSION_COLUMNS: (
     submission::uuid,
     submission::verdict,
diff --git a/src/models/user.rs b/src/models/user.rs
index 02d477079f77de182a36f63e06fde432d01aadd2..510da99613799eb0003bfba8aea11c71e3d4a19e 100644
--- a/src/models/user.rs
+++ b/src/models/user.rs
@@ -76,7 +76,7 @@ pub fn check_matching_password(
     {
         Some(user) => Ok(
             if argon2::verify_encoded(&user.hashed_password, password.as_bytes())? {
-                PasswordMatched::PasswordMatches(get_user_by_name(connection, &name)?)
+                PasswordMatched::PasswordMatches(get_user_by_name(connection, name)?)
             } else {
                 PasswordMatched::PasswordDoesntMatch
             },
diff --git a/src/pages/create_contest.rs b/src/pages/create_contest.rs
index aaeb9c0e9a81ffe8499296a3d6865d1d14dbfbcf..a96705535e378486e4b8eaffcfa038307f602467 100644
--- a/src/pages/create_contest.rs
+++ b/src/pages/create_contest.rs
@@ -94,7 +94,7 @@ async fn create_contest(
 
     let polygon_zip = form
         .polygon_zip
-        .ok_or(PageError::Validation("Arquivo não informado".into()))?;
+        .ok_or_else(|| PageError::Validation("Arquivo não informado".into()))?;
     let imported = import_contest::import_file(polygon_zip)
         .map_err(|e| PageError::Validation(format!("Não foi possível importar: {}", e)))?;
     let mut connection = pool.get()?;
@@ -124,7 +124,7 @@ async fn create_contest(
 
     fn polygon_url_to_id_without_revision(url: String) -> String {
         url.replace("https://polygon.codeforces.com/", "polygon.")
-            .replace("/", ".")
+            .replace('/', ".")
     }
 
     let problem_label: HashMap<String, String> =
@@ -176,7 +176,7 @@ async fn create_contest(
         let mut filenames = zip
             .file_names()
             .filter(|name| files_regex.is_match(name))
-            .map(|s| s.to_string())
+            .map(std::string::ToString::to_string)
             .collect::<Vec<_>>();
         filenames.sort();
         for name in filenames {
@@ -188,7 +188,7 @@ async fn create_contest(
                 .as_str();
             let data_path = format!("/data/{}/{}", problem_id, relative_path);
 
-            if name.ends_with("/") {
+            if name.ends_with('/') {
                 info!("Creating directory {} into {}", name, data_path);
                 create_dir_all(data_path)?;
                 continue;
@@ -211,7 +211,7 @@ async fn create_contest(
             .solution
             .iter()
             .find(|s| s.tag == "main")
-            .ok_or(PageError::Validation("No main solution".into()))?
+            .ok_or_else(|| PageError::Validation("No main solution".into()))?
             .source;
 
         let problem = problem::upsert_problem(
@@ -268,17 +268,17 @@ async fn create_contest(
                     .join(import_contest::format_width(&problem.test_pattern, i));
                 info!("Extracting {:#?} from zip", test_name);
                 std::io::copy(
-                    &mut zip.by_name(&test_name.to_str().unwrap())?,
+                    &mut zip.by_name(test_name.to_str().unwrap())?,
                     &mut File::create(PathBuf::from("/data/").join(&test_path))?,
                 )?;
             } else {
-                let cmd: Vec<_> = test.cmd.as_ref().unwrap().split(" ").collect();
+                let cmd: Vec<_> = test.cmd.as_ref().unwrap().split(' ').collect();
                 let run_stats = language::run_cached(
                     &job_sender,
                     &job_result_sender,
                     &"cpp.17.g++".into(),
-                    format!("./{}/files/{}.cpp", problem.id, cmd.get(0).unwrap()),
-                    cmd[1..].iter().map(|s| s.clone().into()).collect(),
+                    format!("./{}/files/{}.cpp", problem.id, cmd.first().unwrap()),
+                    cmd[1..].iter().map(|s| <&str>::clone(s).into()).collect(),
                     None,
                     Some(test_path.clone()),
                     problem.memory_limit_bytes / 1_024,
@@ -325,9 +325,9 @@ async fn create_contest(
                 problem.id, problem.main_solution_path
             )))?,
             problem.test_count,
-            format!("./{}/{}", problem.id, problem.test_pattern).into(),
+            format!("./{}/{}", problem.id, problem.test_pattern),
             problem.checker_language,
-            format!("./{}/{}", problem.id, problem.checker_path).into(),
+            format!("./{}/{}", problem.id, problem.checker_path),
             problem.memory_limit_bytes / 1_024,
             problem.time_limit_ms,
         )
@@ -340,7 +340,7 @@ async fn create_contest(
                 contest::NewContestProblems {
                     label: problem_label
                         .get(&problem_id_without_revision)
-                        .ok_or(PageError::Validation(
+                        .ok_or_else(|| PageError::Validation(
                             "Arquivo não contém problemas listados".into(),
                         ))?
                         .to_string()
diff --git a/src/pages/create_submission.rs b/src/pages/create_submission.rs
index fdd83933a13759db5987e6ee75e226ad73c176db..1ad7ed3cc5fc7dbbdc4caa89263ad216b9a9b290 100644
--- a/src/pages/create_submission.rs
+++ b/src/pages/create_submission.rs
@@ -28,7 +28,7 @@ async fn create_submission(
 
     languages
         .get(&form.language)
-        .ok_or(PageError::Validation("Linguagem inexistente".into()))?;
+        .ok_or_else(|| PageError::Validation("Linguagem inexistente".into()))?;
 
     if !logged_user.is_admin && form.language != "cpp.17.g++" {
         return Err(PageError::Validation(
@@ -66,9 +66,9 @@ async fn create_submission(
             which: Some(job::Which::Judgement(job::Judgement {
                 source_text: (&form.source_text).into(),
                 test_count: metadata.test_count,
-                test_pattern: format!("./{}/{}", metadata.id, metadata.test_pattern).into(),
+                test_pattern: format!("./{}/{}", metadata.id, metadata.test_pattern),
                 checker_language: metadata.checker_language,
-                checker_source_path: format!("./{}/{}", metadata.id, metadata.checker_path).into(),
+                checker_source_path: format!("./{}/{}", metadata.id, metadata.checker_path),
             })),
         })
         .await?;
diff --git a/src/pages/get_contest_scoreboard_by_id.rs b/src/pages/get_contest_scoreboard_by_id.rs
index 61c33dcc75d2a73b1acdb92952235a377c2e40d4..e2c55da2dfb896cc85215af2ef850cdf8163394a 100644
--- a/src/pages/get_contest_scoreboard_by_id.rs
+++ b/src/pages/get_contest_scoreboard_by_id.rs
@@ -42,13 +42,13 @@ async fn get_contest_scoreboard_by_id(
     let scores = problem::get_problems_by_contest_id_with_score(&mut connection, contest_id)?;
     let submissions =
         submission::get_submissions_user_by_contest(&mut connection, logged_user.id, contest_id)?;
-    let mut scores: Vec<_> = scores.into_iter().group_by(|e| e.user_name.as_ref().map(|s| s.clone())).into_iter().map(|(user_name, problems)| {
+    let mut scores: Vec<_> = scores.into_iter().group_by(|e| e.user_name.as_ref().cloned()).into_iter().map(|(user_name, problems)| {
     let problems: Vec<_> = problems.map(|p| get_formatted_problem_by_contest_with_score(&p, &contest)).collect();
 
     Score {
         user_name,
-        solved_count: i64::try_from(problems.iter().filter(|p| p.first_ac_submission_time != "").count()).unwrap(),
-        penalty: problems.iter().filter(|p| p.first_ac_submission_time != "")
+        solved_count: i64::try_from(problems.iter().filter(|p| !p.first_ac_submission_time.is_empty()).count()).unwrap(),
+        penalty: problems.iter().filter(|p| !p.first_ac_submission_time.is_empty())
             .map(|p| match p.first_ac_submission_minutes {
                 Some(x) if x >= 0 => x,
                 _ => 0,
diff --git a/src/pages/get_problems.rs b/src/pages/get_problems.rs
index 6050b7f7b5d989d5f4af90072c82e0bfaaf3040b..e07654ed9beb15008425bd98b49f3b2ff26e4187 100644
--- a/src/pages/get_problems.rs
+++ b/src/pages/get_problems.rs
@@ -36,7 +36,7 @@ pub async fn get_problems(
                     label: p.label.clone(),
                     memory_limit_mib: p.memory_limit_bytes / 1_024 / 1_024,
                     time_limit: format!("{}", f64::from(p.time_limit_ms) / 1000.0)
-                        .replacen(".", ",", 1),
+                        .replacen('.', ",", 1),
                     user_accepted_count: p.user_accepted_count,
                 })
                 .collect(),
diff --git a/src/pages/get_submissions.rs b/src/pages/get_submissions.rs
index 69af7849a2925c4861c34436ea4121747fd18ee6..2fbaa90e248c0d03119f33a38a61bc25a04ea7d0 100644
--- a/src/pages/get_submissions.rs
+++ b/src/pages/get_submissions.rs
@@ -18,11 +18,11 @@ pub fn render_submissions(
     }
 
     render(
-        &hb,
+        hb,
         "submissions",
         &Context {
             base,
-            submissions: get_formatted_submissions(&tz, &submissions),
+            submissions: get_formatted_submissions(tz, &submissions),
         },
     )
 }
diff --git a/src/pages/mod.rs b/src/pages/mod.rs
index c2641a71d47bcbc2d2619280b7700ecccacd9dbc..cc9cec79fd07a33148e43a79a00c2ccb79e3a54f 100644
--- a/src/pages/mod.rs
+++ b/src/pages/mod.rs
@@ -107,19 +107,16 @@ fn get_formatted_problem_by_contest_with_score(
                 Some(cs) => format_duration(t - cs),
                 None => "*".into(),
             })
-            .unwrap_or("".into()),
+            .unwrap_or_else(|| "".into()),
         first_ac_submission_minutes: p.first_ac_submission_instant.and_then(|t| {
-            match contest.start_instant {
-                Some(cs) => Some((t - cs).num_minutes()),
-                None => None,
-            }
+            contest.start_instant.map(|cs| (t - cs).num_minutes())
         }),
         failed_submissions: p.failed_submissions,
         id: p.id,
         name: p.name.clone(),
         label: p.label.clone(),
         memory_limit_mib: p.memory_limit_bytes / 1_024 / 1_024,
-        time_limit: format!("{}", f64::from(p.time_limit_ms) / 1000.0).replacen(".", ",", 1),
+        time_limit: format!("{}", f64::from(p.time_limit_ms) / 1000.0).replacen('.', ",", 1),
         user_accepted_count: p.user_accepted_count,
     }
 }
@@ -130,8 +127,7 @@ fn assert_contest_not_started(
 ) -> Result<(), PageError> {
     if contest
         .start_instant
-        .map(|s| s > Local::now().naive_utc())
-        .unwrap_or(false)
+        .map_or(false, |s| s > Local::now().naive_utc())
         && !logged_user.is_admin
     {
         return Err(PageError::Forbidden(
@@ -162,20 +158,17 @@ fn format_utc_date_time(tz: &Tz, input: NaiveDateTime) -> String {
 
 fn get_formatted_submissions(
     tz: &Tz,
-    vec: &Vec<(Submission, ContestProblem, User)>,
+    vec: &[(Submission, ContestProblem, User)],
 ) -> Vec<FormattedSubmission> {
     vec.iter()
         .map(|(submission, contest_problem, user)| FormattedSubmission {
             uuid: (&submission.uuid).into(),
             verdict: submission
                 .verdict
-                .as_ref()
-                .map(|s| String::from(s))
-                .unwrap_or("WJ".into())
-                .into(),
+                .as_ref().map_or_else(|| "WJ".into(), String::from),
             problem_label: contest_problem.label.clone(),
             submission_instant: format_utc_date_time(tz, submission.submission_instant),
-            error_output: submission.error_output.as_ref().map(|s| s.into()),
+            error_output: submission.error_output.as_ref().map(std::convert::Into::into),
             user_name: user.name.clone(),
             time_ms: submission.time_ms,
             memory: match submission.memory_kib {
@@ -208,9 +201,9 @@ fn get_formatted_contest(tz: &Tz, contest: &Contest) -> FormattedContest {
     FormattedContest {
         id: contest.id,
         name: contest.name.clone(),
-        start_instant: contest.start_instant.map(|i| format_utc_date_time(&tz, i)),
-        end_instant: contest.end_instant.map(|i| format_utc_date_time(&tz, i)),
-        creation_instant: format_utc_date_time(&tz, contest.creation_instant),
+        start_instant: contest.start_instant.map(|i| format_utc_date_time(tz, i)),
+        end_instant: contest.end_instant.map(|i| format_utc_date_time(tz, i)),
+        creation_instant: format_utc_date_time(tz, contest.creation_instant),
         grade_ratio: contest.grade_ratio,
         grade_after_ratio: contest.grade_after_ratio,
         accepted_count: 0,
@@ -225,9 +218,9 @@ fn get_formatted_contest_acs(tz: &Tz, contest: &ContestWithAcs) -> FormattedCont
     FormattedContest {
         id: contest.id,
         name: contest.name.clone(),
-        start_instant: contest.start_instant.map(|i| format_utc_date_time(&tz, i)),
-        end_instant: contest.end_instant.map(|i| format_utc_date_time(&tz, i)),
-        creation_instant: format_utc_date_time(&tz, contest.creation_instant),
+        start_instant: contest.start_instant.map(|i| format_utc_date_time(tz, i)),
+        end_instant: contest.end_instant.map(|i| format_utc_date_time(tz, i)),
+        creation_instant: format_utc_date_time(tz, contest.creation_instant),
         grade_ratio: contest.grade_ratio,
         grade_after_ratio: contest.grade_after_ratio,
         accepted_count: contest.accepted_count,
@@ -245,7 +238,7 @@ fn get_formatted_contest_acs(tz: &Tz, contest: &ContestWithAcs) -> FormattedCont
                         None => 0.0,
                     })
             )
-            .replacen(".", ",", 1),
+            .replacen('.', ",", 1),
             None => "".into(),
         },
     }
diff --git a/src/pages/prelude.rs b/src/pages/prelude.rs
index c65d78026103a20e7b81f01d821b162545a79a15..df74491c032bb5b21ae539894ac5e877b2ae69ee 100644
--- a/src/pages/prelude.rs
+++ b/src/pages/prelude.rs
@@ -150,9 +150,7 @@ pub fn redirect_to_referer(message: String, request: &HttpRequest) -> HttpRespon
     let referer = request
         .headers()
         .get("Referer")
-        .and_then(|h| h.to_str().ok())
-        .map(|s| s.into())
-        .unwrap_or(env::var("BASE_URL").expect("BASE_URL environment variable is not set"));
+        .and_then(|h| h.to_str().ok()).map_or_else(|| env::var("BASE_URL").expect("BASE_URL environment variable is not set"), std::convert::Into::into);
     FlashMessage::info(message).send();
     HttpResponse::SeeOther()
         .append_header((header::LOCATION, HeaderValue::from_str(&referer).unwrap()))
diff --git a/src/setup.rs b/src/setup.rs
index c85a0e74dd0f945481aecdd72e91e2f44cac0e77..e1fba9967a8ae82f4df01b57360b98ee5a96d4d1 100644
--- a/src/setup.rs
+++ b/src/setup.rs
@@ -29,10 +29,10 @@ pub fn setup_admin(connection: &mut PgConnection) {
             .expect("Error saving new user");
         }
         PasswordMatched::PasswordMatches(_) => {
-            info!("Admin already created and is using default password.",)
+            info!("Admin already created and is using default password.",);
         }
         PasswordMatched::PasswordDoesntMatch => {
-            info!("Admin already created and is not using the default password.",)
+            info!("Admin already created and is not using the default password.",);
         }
     }
 }