diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000000000000000000000000000000000000..45edb19df793bf299025d157846ee84ae901c192 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,4 @@ +reorder_impl_items = true +imports_granularity = "Module" +group_imports = "StdExternalCrate" +use_try_shorthand = true diff --git a/src/broadcaster.rs b/src/broadcaster.rs index c71b9685e6134516d0a2d9c717354dc241ab34f1..5082e5847a90cd3617212298d600114c2ca48bc9 100644 --- a/src/broadcaster.rs +++ b/src/broadcaster.rs @@ -1,15 +1,17 @@ -use crate::queue::job_protocol::{job_result, JobResult}; -use actix_web::rt::time::{interval_at, Instant}; -use actix_web::web::{Bytes, Data}; -use actix_web::Error; -use futures::Stream; use std::pin::Pin; use std::sync::Mutex; use std::task::{Context, Poll}; use std::time::Duration; + +use actix_web::rt::time::{interval_at, Instant}; +use actix_web::web::{Bytes, Data}; +use actix_web::Error; +use futures::Stream; use tokio::sync::broadcast; use tokio::sync::mpsc::{channel, Receiver, Sender}; +use crate::queue::job_protocol::{job_result, JobResult}; + pub struct Broadcaster { clients: Vec<Sender<Bytes>>, } diff --git a/src/import_contest.rs b/src/import_contest.rs index 2d77f528dd2b35504bc8386a07a108ad6cb403bc..bbeac6228aba2fc3ef4dd38de86548b1e47e7c19 100644 --- a/src/import_contest.rs +++ b/src/import_contest.rs @@ -1,12 +1,13 @@ -use lazy_static::lazy_static; -use regex::Captures; -use regex::Regex; use std::io::{Read, Seek}; + +use lazy_static::lazy_static; +use regex::{Captures, Regex}; use zip::ZipArchive; mod error { - use quick_xml::de::DeError; use std::io; + + use quick_xml::de::DeError; use thiserror::Error; use zip::result::ZipError; @@ -37,10 +38,12 @@ mod xml { } pub mod prelude { - pub use super::super::ImportContestError; - pub use serde::Deserialize; pub use std::io::{Read, Seek}; + + pub use serde::Deserialize; pub use zip::ZipArchive; + + pub use super::super::ImportContestError; } pub mod contest { diff --git a/src/language.rs b/src/language.rs index 2272ae6f30db073f05a9ea8a89ae8d4370fab577..0c7d4726141bd0cc4c36213dc6d914c9e18bba2b 100644 --- a/src/language.rs +++ b/src/language.rs @@ -1,11 +1,11 @@ -use crate::queue::job_protocol::job_result; -use crate::queue::job_protocol::{job, Job, JobResult}; use async_channel::Sender; use log::info; use thiserror::Error; use tokio::sync::broadcast; use uuid::Uuid; +use crate::queue::job_protocol::{job, job_result, Job, JobResult}; + #[derive(Error, Debug, Clone)] #[error("job failed")] struct JobFailedError; diff --git a/src/lib.rs b/src/lib.rs index 4b4c22247a98385c56f8875fb05925436426aed6..f67ac48b43161ce875ad2ef8a7fdd755153d51e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ -pub mod import_contest; mod queue; +pub mod import_contest; + pub mod job_protocol { pub use crate::queue::job_protocol::*; } diff --git a/src/main.rs b/src/main.rs index 083bc5026c85ae0549784f9ec4d7214dea250b4e..65f3e9aee25dd0d59414de46e50b3288ec924906 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,24 +1,64 @@ -use lazy_static::lazy_static; -use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::convert::TryFrom; +use std::error::Error; +use std::fs::{create_dir_all, File}; +use std::future::Future; +use std::io::{Cursor, Read, Write}; +use std::iter::FromIterator; +use std::path::PathBuf; +use std::pin::Pin; +use std::sync::{Arc, Mutex}; +use std::time::Duration; +use std::{env, fs, str}; -use actix_files::Files; -use actix_identity::Identity; -use actix_identity::IdentityMiddleware; +use actix_files::{Files, NamedFile}; +use actix_identity::{Identity, IdentityMiddleware}; +use actix_multipart::Multipart; use actix_session::storage::CookieSessionStore; -use actix_session::Session; -use actix_session::SessionMiddleware; +use actix_session::{Session, SessionMiddleware}; +use actix_web::cookie::Key; +use actix_web::dev::Payload; +use actix_web::http::header::{ContentType, HeaderValue}; +use actix_web::http::{header, StatusCode}; use actix_web::middleware::{ErrorHandlerResponse, ErrorHandlers}; -use actix_web::HttpResponse; -use actix_web::{dev, get, http, middleware, post, web, App, HttpServer}; +use actix_web::web::Data; +use actix_web::{ + dev, get, http, middleware, post, web, App, FromRequest, HttpMessage, HttpRequest, + HttpResponse, HttpServer, +}; +use actix_web_flash_messages::storage::CookieMessageStore; +use actix_web_flash_messages::{ + FlashMessage, FlashMessagesFramework, IncomingFlashMessages, Level, +}; +use async_channel::Sender; +use base64; +use broadcaster::Broadcaster; use chrono::prelude::*; +use chrono_tz::Tz; +use contest::{Contest, ContestWithAcs}; +use dashmap::DashMap; use diesel::pg::PgConnection; use diesel::r2d2::ConnectionManager; +use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; +use futures::{StreamExt, TryFutureExt, TryStreamExt}; use handlebars::Handlebars; +use itertools::Itertools; +use lazy_static::lazy_static; +use listenfd::ListenFd; use log::{error, info}; -use models::submission; -use models::user; -use std::env; -use std::fs::File; +use models::problem::ProblemByContest; +use models::{contest, problem, submission, user}; +use problem::{ProblemByContestMetadata, ProblemByContestWithScore}; +use queue::job_protocol::job_queue_server::JobQueueServer; +use queue::job_protocol::{job, job_result, Job, JobResult, Language}; +use queue::JobQueuer; +use regex::Regex; +use serde::{Deserialize, Serialize}; +use submission::{ContestProblem, Submission, SubmissionCompletion}; +use thiserror::Error; +use tokio::sync::broadcast; +use tonic::transport::Server; +use user::{PasswordMatched, User, UserHashingError}; use uuid::Uuid; mod broadcaster; @@ -29,24 +69,7 @@ mod queue; mod schema; mod setup; -use broadcaster::Broadcaster; -use listenfd::ListenFd; -use std::sync::Mutex; type DbPool = r2d2::Pool<ConnectionManager<PgConnection>>; -use actix_web::web::Data; -use actix_web::HttpMessage; -use async_channel::Sender; -use chrono_tz::Tz; -use futures::TryFutureExt; -use queue::job_protocol::job_queue_server::JobQueueServer; -use queue::job_protocol::{job, job_result, Job, JobResult, Language}; -use queue::JobQueuer; -use std::error::Error; -use std::fs; -use std::time::Duration; -use submission::SubmissionCompletion; -use tokio::sync::broadcast; -use tonic::transport::Server; async fn update_database( mut job_result_receiver: broadcast::Receiver<JobResult>, @@ -98,18 +121,6 @@ async fn update_database( } } -use base64; - -use actix_web::cookie::Key; -use diesel_migrations::MigrationHarness; -use diesel_migrations::{embed_migrations, EmbeddedMigrations}; -pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!(); - -use actix_web_flash_messages::storage::CookieMessageStore; -use actix_web_flash_messages::{FlashMessagesFramework, Level}; - -use problem::ProblemByContestMetadata; -use submission::Submission; fn create_job_from_submission(submission: Submission, metadata: ProblemByContestMetadata) -> Job { Job { uuid: submission.uuid, @@ -127,6 +138,8 @@ fn create_job_from_submission(submission: Submission, metadata: ProblemByContest } } +pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!(); + #[actix_web::main] async fn main() -> Result<(), Box<dyn Error>> { std::env::set_var("RUST_LOG", "info"); @@ -271,9 +284,6 @@ async fn main() -> Result<(), Box<dyn Error>> { Ok(()) } -use actix_web::http::StatusCode; -use thiserror::Error; - #[derive(Error, Debug)] #[error("unauthorized")] struct UnauthorizedError {} @@ -377,8 +387,6 @@ impl actix_web::error::ResponseError for GetError { } } -use actix_web_flash_messages::IncomingFlashMessages; - type GetResult = Result<HttpResponse, GetError>; #[derive(Serialize)] @@ -388,10 +396,6 @@ struct BaseContext { base_url: String, } -use actix_web::dev::Payload; -use actix_web::FromRequest; -use std::future::Future; -use std::pin::Pin; impl FromRequest for BaseContext { type Error = actix_web::Error; type Future = Pin<Box<dyn Future<Output = Result<Self, Self::Error>>>>; @@ -431,8 +435,6 @@ async fn get_me(base: BaseContext, identity: Identity, hb: web::Data<Handlebars< Ok(HttpResponse::Ok().body(hb.render("me", &Context { base })?)) } -use actix_files::NamedFile; - #[get("/problems/{id}/assets/{filename}")] async fn get_problem_by_id_assets( identity: Identity, @@ -452,11 +454,6 @@ async fn get_problem_by_id_assets( Ok(NamedFile::open(file_path)?) } -use actix_web::http::header; -use actix_web::http::header::ContentType; -use actix_web::http::header::HeaderValue; -use actix_web_flash_messages::FlashMessage; - fn render_401<B>(mut res: dev::ServiceResponse<B>) -> actix_web::Result<ErrorHandlerResponse<B>> { FlashMessage::error("Você precisa estar logado para acessar esta página").send(); res.response_mut().headers_mut().insert( @@ -482,9 +479,6 @@ struct LoginForm { password: String, } -use models::problem; -use models::problem::ProblemByContest; - fn get_identity(identity: &Identity) -> Option<LoggedUser> { let identity = identity.id(); identity @@ -514,8 +508,6 @@ fn format_duration(duration: chrono::Duration) -> String { ) } -use contest::{Contest, ContestWithAcs}; - #[derive(Serialize)] struct FormattedProblemByContestWithScore { pub first_ac_submission_time: String, @@ -529,8 +521,6 @@ struct FormattedProblemByContestWithScore { pub time_limit: String, } -use problem::ProblemByContestWithScore; - fn get_formatted_problem_by_contest_with_score( p: &ProblemByContestWithScore, contest: &Contest, @@ -607,9 +597,6 @@ async fn get_contest_by_id( )) } -use itertools::Itertools; -use std::convert::TryFrom; - #[get("/contests/{id}/scoreboard")] async fn get_contest_scoreboard_by_id( base: BaseContext, @@ -796,8 +783,6 @@ async fn post_login( ) -> PostResult { let mut connection = pool.get()?; - use user::PasswordMatched; - use user::UserHashingError; match web::block(move || { user::check_matching_password(&mut connection, &form.name, &form.password) }) @@ -860,8 +845,6 @@ fn format_utc_date_time(tz: &Tz, input: NaiveDateTime) -> String { .to_string() } -use submission::ContestProblem; -use user::User; fn get_formatted_submissions( tz: &Tz, vec: &Vec<(Submission, ContestProblem, User)>, @@ -1088,12 +1071,6 @@ struct SubmissionForm { source_text: String, } -use dashmap::DashMap; -use std::collections::HashMap; -use std::sync::Arc; - -use actix_web::HttpRequest; - fn redirect_to_root() -> HttpResponse { HttpResponse::SeeOther() .append_header(( @@ -1140,7 +1117,6 @@ async fn change_password( let mut connection = pool.get()?; - use user::PasswordMatched; match user::change_password( &mut connection, identity.id, @@ -1478,19 +1454,6 @@ async fn get_contests( )?)) } -use crate::models::contest; -use actix_multipart::Multipart; -use futures::StreamExt; -use futures::TryStreamExt; -use regex::Regex; -use std::fs::create_dir_all; -use std::io::Cursor; -use std::io::Read; -use std::io::Write; -use std::iter::FromIterator; -use std::path::PathBuf; -use std::str; - #[post("/contests/")] async fn create_contest( identity: Identity, diff --git a/src/models/contest.rs b/src/models/contest.rs index 410c57e6e4cbb2617afe0ba15676e6ce75a4d075..34187dcdd6802ed23234db93b4a22b5016e8f3b4 100644 --- a/src/models/contest.rs +++ b/src/models/contest.rs @@ -2,8 +2,7 @@ use chrono::prelude::*; use diesel::insert_into; use diesel::prelude::*; -use crate::schema::contest; -use crate::schema::contest_problems; +use crate::schema::{contest, contest_problems}; #[derive(Queryable)] pub struct Contest { diff --git a/src/models/problem.rs b/src/models/problem.rs index 34e46ccd3453e9bfa32b0c102acb83d5d5de0b70..9cc1b359205e0e62237828485b118db7456b63e9 100644 --- a/src/models/problem.rs +++ b/src/models/problem.rs @@ -4,8 +4,7 @@ use diesel::pg::PgConnection; use diesel::prelude::*; use serde::Serialize; -use crate::schema::contest_problems; -use crate::schema::problem; +use crate::schema::{contest_problems, problem}; #[derive(Queryable)] pub struct Problem { diff --git a/src/models/submission.rs b/src/models/submission.rs index 077d3e089066a1d0ad9504dd4bace051d2210460..ac095c5d0eb2b546491bc2a1a6566017d03970b1 100644 --- a/src/models/submission.rs +++ b/src/models/submission.rs @@ -1,14 +1,11 @@ -use crate::contest::{Contest, CONTEST_COLUMNS}; -use crate::schema::contest; -use crate::schema::contest_problems; -use crate::schema::problem; -use crate::schema::submission; -use crate::schema::user; -use crate::user::{User, USER_COLUMNS}; use chrono::prelude::*; use diesel::insert_into; use diesel::prelude::*; +use crate::contest::{Contest, CONTEST_COLUMNS}; +use crate::schema::{contest, contest_problems, problem, submission, user}; +use crate::user::{User, USER_COLUMNS}; + #[derive(Queryable)] pub struct Submission { pub uuid: String, diff --git a/src/models/user.rs b/src/models/user.rs index 0d9a04ff87be8a0f9ee6110615262530788c4ff4..02d477079f77de182a36f63e06fde432d01aadd2 100644 --- a/src/models/user.rs +++ b/src/models/user.rs @@ -1,9 +1,10 @@ +use std::env; + use chrono::prelude::*; use diesel::insert_into; use diesel::pg::PgConnection; use diesel::prelude::*; use serde::Serialize; -use std::env; use thiserror::Error; use crate::schema::user; diff --git a/src/queue.rs b/src/queue.rs index ebd293ed9e13ee4ac2ca2c1ab64dc53a56f2a436..237418852b9e919c625489afe4c212c95f5935b5 100644 --- a/src/queue.rs +++ b/src/queue.rs @@ -1,9 +1,10 @@ +use std::sync::Arc; + use async_channel::Receiver; use dashmap::DashMap; use job_protocol::job_queue_server::JobQueue; use job_protocol::{GetJobRequest, Job, JobResult, JobResultConfirmation, Language}; use log::info; -use std::sync::Arc; use tokio::sync::broadcast; use tonic::{Request, Response, Status}; diff --git a/src/setup.rs b/src/setup.rs index cd1807086cede4db5d5beb2c53133258a57d8b0b..c85a0e74dd0f945481aecdd72e91e2f44cac0e77 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -1,9 +1,9 @@ use chrono::prelude::*; +use diesel::PgConnection; use log::info; use crate::models::user; use crate::models::user::NewUser; -use diesel::PgConnection; pub fn setup_admin(connection: &mut PgConnection) { use user::PasswordMatched;