diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bee85b591..14121e1c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,9 @@ jobs: - name: Build docs.rs run: cargo build --locked + - name: Run clippy + run: cargo clippy -- -D warnings + - name: Prepare the test environment run: | prefix=$(pwd)/ignored/prefix diff --git a/build.rs b/build.rs index 1b07f5913..f037f0672 100644 --- a/build.rs +++ b/build.rs @@ -13,7 +13,8 @@ fn main() { fn write_git_version() { - let git_hash = get_git_hash().unwrap_or("???????".to_owned()); + let maybe_hash = get_git_hash(); + let git_hash = maybe_hash.as_deref().unwrap_or("???????"); let build_date = time::strftime("%Y-%m-%d", &time::now_utc()).unwrap(); let dest_path = Path::new(&env::var("OUT_DIR").unwrap()).join("git_version"); let mut file = File::create(&dest_path).unwrap(); diff --git a/src/bin/cratesfyi.rs b/src/bin/cratesfyi.rs index df186b179..d70b5ea9c 100644 --- a/src/bin/cratesfyi.rs +++ b/src/bin/cratesfyi.rs @@ -8,6 +8,7 @@ use cratesfyi::Server; use cratesfyi::db::{add_path_into_database, connect_db}; +#[allow(clippy::cognitive_complexity)] pub fn main() { logger_init(); @@ -169,7 +170,7 @@ pub fn main() { let mut docbuilder = DocBuilder::new(docbuilder_opts); - if let Some(_) = matches.subcommand_matches("world") { + if matches.subcommand_matches("world").is_some() { docbuilder.load_cache().expect("Failed to load cache"); let mut builder = RustwideBuilder::init().unwrap(); builder.build_world(&mut docbuilder).expect("Failed to build world"); @@ -197,11 +198,11 @@ pub fn main() { } else if matches.subcommand_matches("add-essential-files").is_some() { let mut builder = RustwideBuilder::init().unwrap(); builder.add_essential_files().expect("failed to add essential files"); - } else if let Some(_) = matches.subcommand_matches("lock") { + } else if matches.subcommand_matches("lock").is_some() { docbuilder.lock().expect("Failed to lock"); - } else if let Some(_) = matches.subcommand_matches("unlock") { + } else if matches.subcommand_matches("unlock").is_some() { docbuilder.unlock().expect("Failed to unlock"); - } else if let Some(_) = matches.subcommand_matches("print-options") { + } else if matches.subcommand_matches("print-options").is_some() { println!("{:?}", docbuilder.options()); } @@ -211,20 +212,20 @@ pub fn main() { .expect("Version should be an integer")); db::migrate(version, &connect_db().expect("failed to connect to the database")) .expect("Failed to run database migrations"); - } else if let Some(_) = matches.subcommand_matches("update-github-fields") { + } else if matches.subcommand_matches("update-github-fields").is_some() { cratesfyi::utils::github_updater().expect("Failed to update github fields"); } else if let Some(matches) = matches.subcommand_matches("add-directory") { add_path_into_database(&db::connect_db().unwrap(), matches.value_of("PREFIX").unwrap_or(""), matches.value_of("DIRECTORY").unwrap()) .expect("Failed to add directory into database"); - } else if let Some(_) = matches.subcommand_matches("update-release-activity") { + } else if matches.subcommand_matches("update-release-activity").is_some() { // FIXME: This is actually util command not database cratesfyi::utils::update_release_activity().expect("Failed to update release activity"); - } else if let Some(_) = matches.subcommand_matches("update-search-index") { + } else if matches.subcommand_matches("update-search-index").is_some() { let conn = db::connect_db().unwrap(); db::update_search_index(&conn).expect("Failed to update search index"); - } else if let Some(_) = matches.subcommand_matches("move-to-s3") { + } else if matches.subcommand_matches("move-to-s3").is_some() { let conn = db::connect_db().unwrap(); let mut count = 1; let mut total = 0; @@ -243,7 +244,7 @@ pub fn main() { } else if let Some(matches) = matches.subcommand_matches("blacklist") { let conn = db::connect_db().expect("failed to connect to the database"); - if let Some(_) = matches.subcommand_matches("list") { + if matches.subcommand_matches("list").is_some() { let crates = db::blacklist::list_crates(&conn).expect("failed to list crates on blacklist"); println!("{}", crates.join("\n")); @@ -260,7 +261,7 @@ pub fn main() { } else if let Some(matches) = matches.subcommand_matches("start-web-server") { Server::start(Some(matches.value_of("SOCKET_ADDR").unwrap_or("0.0.0.0:3000"))); - } else if let Some(_) = matches.subcommand_matches("daemon") { + } else if matches.subcommand_matches("daemon").is_some() { let foreground = matches.subcommand_matches("daemon") .map_or(false, |opts| opts.is_present("FOREGROUND")); cratesfyi::utils::start_daemon(!foreground); @@ -292,8 +293,7 @@ fn logger_init() { record.target(), record.args()) }); - builder.parse_filters(&env::var("RUST_LOG") - .unwrap_or("cratesfyi=info".to_owned())); + builder.parse_filters(env::var("RUST_LOG").ok().as_deref().unwrap_or("cratesfyi=info")); rustwide::logging::init_with(builder.build()); } diff --git a/src/db/add_package.rs b/src/db/add_package.rs index 7ec1b7049..f36423b16 100644 --- a/src/db/add_package.rs +++ b/src/db/add_package.rs @@ -25,6 +25,7 @@ use failure::err_msg; /// /// NOTE: `source_files` refers to the files originally in the crate, /// not the files generated by rustdoc. +#[allow(clippy::too_many_arguments)] pub(crate) fn add_package_into_database(conn: &Connection, metadata_pkg: &MetadataPackage, source_dir: &Path, @@ -45,9 +46,9 @@ pub(crate) fn add_package_into_database(conn: &Connection, let release_id: i32 = { let rows = conn.query("SELECT id FROM releases WHERE crate_id = $1 AND version = $2", - &[&crate_id, &format!("{}", metadata_pkg.version)])?; + &[&crate_id, &metadata_pkg.version.to_string()])?; - if rows.len() == 0 { + if rows.is_empty() { let rows = conn.query("INSERT INTO releases ( crate_id, version, release_time, dependencies, target_name, yanked, build_status, @@ -117,7 +118,7 @@ pub(crate) fn add_package_into_database(conn: &Connection, default_target = $25 WHERE crate_id = $1 AND version = $2", &[&crate_id, - &format!("{}", metadata_pkg.version), + &metadata_pkg.version.to_string(), &cratesio_data.release_time, &dependencies.to_json(), &metadata_pkg.package_name(), @@ -146,9 +147,9 @@ pub(crate) fn add_package_into_database(conn: &Connection, }; - add_keywords_into_database(&conn, &metadata_pkg, &release_id)?; - add_authors_into_database(&conn, &metadata_pkg, &release_id)?; - add_owners_into_database(&conn, &cratesio_data.owners, &crate_id)?; + add_keywords_into_database(&conn, &metadata_pkg, release_id)?; + add_authors_into_database(&conn, &metadata_pkg, release_id)?; + add_owners_into_database(&conn, &cratesio_data.owners, crate_id)?; // Update versions @@ -167,7 +168,7 @@ pub(crate) fn add_package_into_database(conn: &Connection, } } if !found { - versions_array.push(format!("{}", &metadata_pkg.version).to_json()); + versions_array.push(metadata_pkg.version.to_string().to_json()); } } let _ = conn.query("UPDATE crates SET versions = $1 WHERE id = $2", @@ -180,7 +181,7 @@ pub(crate) fn add_package_into_database(conn: &Connection, /// Adds a build into database pub(crate) fn add_build_into_database(conn: &Connection, - release_id: &i32, + release_id: i32, res: &BuildResult) -> Result { debug!("Adding build into database"); @@ -189,7 +190,7 @@ pub(crate) fn add_build_into_database(conn: &Connection, build_status, output) VALUES ($1, $2, $3, $4, $5) RETURNING id", - &[release_id, + &[&release_id, &res.rustc_version, &res.docsrs_version, &res.successful, @@ -201,7 +202,7 @@ pub(crate) fn add_build_into_database(conn: &Connection, fn initialize_package_in_database(conn: &Connection, pkg: &MetadataPackage) -> Result { let mut rows = conn.query("SELECT id FROM crates WHERE name = $1", &[&pkg.name])?; // insert crate into database if it is not exists - if rows.len() == 0 { + if rows.is_empty() { rows = conn.query("INSERT INTO crates (name) VALUES ($1) RETURNING id", &[&pkg.name])?; } @@ -225,13 +226,13 @@ fn convert_dependencies(pkg: &MetadataPackage) -> Vec<(String, String, String)> /// Reads readme if there is any read defined in Cargo.toml of a Package fn get_readme(pkg: &MetadataPackage, source_dir: &Path) -> Result> { - let readme_path = source_dir.join(pkg.readme.clone().unwrap_or("README.md".to_owned())); + let readme_path = source_dir.join(pkg.readme.as_deref().unwrap_or("README.md")); if !readme_path.exists() { return Ok(None); } - let mut reader = fs::File::open(readme_path).map(|f| BufReader::new(f))?; + let mut reader = fs::File::open(readme_path).map(BufReader::new)?; let mut readme = String::new(); reader.read_to_string(&mut readme)?; @@ -262,7 +263,7 @@ fn get_rustdoc(pkg: &MetadataPackage, source_dir: &Path) -> Result Result> { - let reader = fs::File::open(file_path).map(|f| BufReader::new(f))?; + let reader = fs::File::open(file_path).map(BufReader::new)?; let mut rustdoc = String::new(); for line in reader.lines() { @@ -356,17 +357,17 @@ fn get_release_time_yanked_downloads( } } - Ok((release_time.unwrap_or(time::get_time()), yanked.unwrap_or(false), downloads.unwrap_or(0))) + Ok((release_time.unwrap_or_else(time::get_time), yanked.unwrap_or(false), downloads.unwrap_or(0))) } /// Adds keywords into database -fn add_keywords_into_database(conn: &Connection, pkg: &MetadataPackage, release_id: &i32) -> Result<()> { +fn add_keywords_into_database(conn: &Connection, pkg: &MetadataPackage, release_id: i32) -> Result<()> { for keyword in &pkg.keywords { let slug = slugify(&keyword); let keyword_id: i32 = { let rows = conn.query("SELECT id FROM keywords WHERE slug = $1", &[&slug])?; - if rows.len() > 0 { + if !rows.is_empty() { rows.get(0).get(0) } else { conn.query("INSERT INTO keywords (name, slug) VALUES ($1, $2) RETURNING id", @@ -377,7 +378,7 @@ fn add_keywords_into_database(conn: &Connection, pkg: &MetadataPackage, release_ }; // add releationship let _ = conn.query("INSERT INTO keyword_rels (rid, kid) VALUES ($1, $2)", - &[release_id, &keyword_id]); + &[&release_id, &keyword_id]); } Ok(()) @@ -386,7 +387,7 @@ fn add_keywords_into_database(conn: &Connection, pkg: &MetadataPackage, release_ /// Adds authors into database -fn add_authors_into_database(conn: &Connection, pkg: &MetadataPackage, release_id: &i32) -> Result<()> { +fn add_authors_into_database(conn: &Connection, pkg: &MetadataPackage, release_id: i32) -> Result<()> { let author_capture_re = Regex::new("^([^><]+)<*(.*?)>*$").unwrap(); for author in &pkg.authors { @@ -397,7 +398,7 @@ fn add_authors_into_database(conn: &Connection, pkg: &MetadataPackage, release_i let author_id: i32 = { let rows = conn.query("SELECT id FROM authors WHERE slug = $1", &[&slug])?; - if rows.len() > 0 { + if !rows.is_empty() { rows.get(0).get(0) } else { conn.query("INSERT INTO authors (name, email, slug) VALUES ($1, $2, $3) @@ -410,7 +411,7 @@ fn add_authors_into_database(conn: &Connection, pkg: &MetadataPackage, release_i // add relationship let _ = conn.query("INSERT INTO author_rels (rid, aid) VALUES ($1, $2)", - &[release_id, &author_id]); + &[&release_id, &author_id]); } } @@ -479,11 +480,11 @@ fn get_owners(pkg: &MetadataPackage) -> Result> { } /// Adds owners into database -fn add_owners_into_database(conn: &Connection, owners: &[CrateOwner], crate_id: &i32) -> Result<()> { +fn add_owners_into_database(conn: &Connection, owners: &[CrateOwner], crate_id: i32) -> Result<()> { for owner in owners { let owner_id: i32 = { let rows = conn.query("SELECT id FROM owners WHERE login = $1", &[&owner.login])?; - if rows.len() > 0 { + if !rows.is_empty() { rows.get(0).get(0) } else { conn.query("INSERT INTO owners (login, avatar, name, email) @@ -497,7 +498,7 @@ fn add_owners_into_database(conn: &Connection, owners: &[CrateOwner], crate_id: // add relationship let _ = conn.query("INSERT INTO owner_rels (cid, oid) VALUES ($1, $2)", - &[crate_id, &owner_id]); + &[&crate_id, &owner_id]); } Ok(()) } diff --git a/src/db/file.rs b/src/db/file.rs index 4052fc023..c4ca87fbd 100644 --- a/src/db/file.rs +++ b/src/db/file.rs @@ -103,7 +103,7 @@ pub fn get_path(conn: &Connection, path: &str) -> Option { FROM files WHERE path = $1", &[&path]).unwrap(); - if rows.len() == 0 { + if rows.is_empty() { None } else { let row = rows.get(0); diff --git a/src/docbuilder/crates.rs b/src/docbuilder/crates.rs index 1f67839f9..53e47b7f1 100644 --- a/src/docbuilder/crates.rs +++ b/src/docbuilder/crates.rs @@ -11,7 +11,7 @@ fn crates_from_file(path: &PathBuf, func: &mut F) -> Result<()> where F: FnMut(&str, &str) -> () { - let reader = fs::File::open(path).map(|f| BufReader::new(f))?; + let reader = fs::File::open(path).map(BufReader::new)?; let mut name = String::new(); let mut versions = Vec::new(); @@ -43,7 +43,7 @@ fn crates_from_file(path: &PathBuf, func: &mut F) -> Result<()> name.clear(); name.push_str(crate_name); - versions.push(format!("{}", vers)); + versions.push(vers.to_string()); } if !name.is_empty() { diff --git a/src/docbuilder/limits.rs b/src/docbuilder/limits.rs index c83673711..43db1f641 100644 --- a/src/docbuilder/limits.rs +++ b/src/docbuilder/limits.rs @@ -96,7 +96,7 @@ fn scale(value: usize, interval: usize, labels: &[&str]) -> String { for label in &labels[1..] { if value / interval >= 1.0 { chosen_label = label; - value = value / interval; + value /= interval; } else { break; } diff --git a/src/docbuilder/metadata.rs b/src/docbuilder/metadata.rs index 181168676..99b9e6ca5 100644 --- a/src/docbuilder/metadata.rs +++ b/src/docbuilder/metadata.rs @@ -77,8 +77,8 @@ pub(super) struct BuildTargets<'a> { impl Metadata { pub(crate) fn from_source_dir(source_dir: &Path) -> Result { - for c in ["Cargo.toml.orig", "Cargo.toml"].iter() { - let manifest_path = source_dir.clone().join(c); + for &c in &["Cargo.toml.orig", "Cargo.toml"] { + let manifest_path = source_dir.join(c); if manifest_path.exists() { return Ok(Metadata::from_manifest(manifest_path)); } @@ -94,7 +94,7 @@ impl Metadata { Err(_) => return Metadata::default(), }; let mut s = String::new(); - if let Err(_) = f.read_to_string(&mut s) { + if f.read_to_string(&mut s).is_err() { return Metadata::default(); } Metadata::from_str(&s) diff --git a/src/docbuilder/mod.rs b/src/docbuilder/mod.rs index 6d833d169..4e02fc15d 100644 --- a/src/docbuilder/mod.rs +++ b/src/docbuilder/mod.rs @@ -32,7 +32,7 @@ pub struct DocBuilder { impl DocBuilder { pub fn new(options: DocBuilderOptions) -> DocBuilder { DocBuilder { - options: options, + options, cache: BTreeSet::new(), db_cache: BTreeSet::new(), } @@ -43,7 +43,7 @@ impl DocBuilder { pub fn load_cache(&mut self) -> Result<()> { debug!("Loading cache"); let path = PathBuf::from(&self.options.prefix).join("cache"); - let reader = fs::File::open(path).map(|f| BufReader::new(f)); + let reader = fs::File::open(path).map(BufReader::new); if let Ok(reader) = reader { for line in reader.lines() { diff --git a/src/docbuilder/options.rs b/src/docbuilder/options.rs index 70dc0c604..02e064935 100644 --- a/src/docbuilder/options.rs +++ b/src/docbuilder/options.rs @@ -27,8 +27,8 @@ impl Default for DocBuilderOptions { generate_paths(cwd); DocBuilderOptions { - prefix: prefix, - crates_io_index_path: crates_io_index_path, + prefix, + crates_io_index_path, keep_build_directory: false, skip_if_exists: false, @@ -63,9 +63,8 @@ impl DocBuilderOptions { let (prefix, crates_io_index_path) = generate_paths(prefix); DocBuilderOptions { - prefix: prefix, - crates_io_index_path: crates_io_index_path, - + prefix, + crates_io_index_path, ..Default::default() } } diff --git a/src/docbuilder/rustwide_builder.rs b/src/docbuilder/rustwide_builder.rs index d1175dfb7..125474742 100644 --- a/src/docbuilder/rustwide_builder.rs +++ b/src/docbuilder/rustwide_builder.rs @@ -90,7 +90,7 @@ impl RustwideBuilder { workspace.purge_all_build_dirs()?; let toolchain_name = std::env::var("CRATESFYI_TOOLCHAIN") - .map(|t| Cow::Owned(t)) + .map(Cow::Owned) .unwrap_or_else(|_| Cow::Borrowed("nightly")); let toolchain = Toolchain::dist(&toolchain_name); @@ -108,7 +108,7 @@ impl RustwideBuilder { let mut targets_to_install = TARGETS .iter() - .map(|t| t.to_string()) + .map(|&t| t.to_string()) .collect::>(); let installed_targets = match self.toolchain.installed_targets(&self.workspace) { Ok(targets) => targets, @@ -146,7 +146,7 @@ impl RustwideBuilder { } self.rustc_version = self.detect_rustc_version()?; - if old_version.as_ref().map(|s| s.as_str()) != Some(&self.rustc_version) { + if old_version.as_deref() != Some(&self.rustc_version) { self.add_essential_files()?; } @@ -210,7 +210,7 @@ impl RustwideBuilder { .iter() .map(|f| (f, true)) .chain(ESSENTIAL_FILES_UNVERSIONED.iter().map(|f| (f, false))); - for (file, versioned) in files { + for (&file, versioned) in files { let segments = file.rsplitn(2, '.').collect::>(); let file_name = if versioned { format!("{}-{}.{}", segments[1], rustc_version, segments[0]) @@ -389,7 +389,7 @@ impl RustwideBuilder { has_docs, has_examples, )?; - add_build_into_database(&conn, &release_id, &res.result)?; + add_build_into_database(&conn, release_id, &res.result)?; doc_builder.add_to_cache(name, version); Ok(res) diff --git a/src/lib.rs b/src/lib.rs index 3af8e597f..9097601a8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ //! [Docs.rs](https://docs.rs) (formerly cratesfyi) is an open source project to host //! documentation of crates for the Rust Programming Language. +#![allow(clippy::cognitive_complexity)] #[macro_use] extern crate log; @@ -34,7 +35,7 @@ pub(crate) static GLOBAL_ALERT: Option = Some(GlobalAlert { /// Version string generated at build time contains last git /// commit hash and build date -pub const BUILD_VERSION: &'static str = concat!(env!("CARGO_PKG_VERSION"), +pub const BUILD_VERSION: &str = concat!(env!("CARGO_PKG_VERSION"), " ", include_str!(concat!(env!("OUT_DIR"), "/git_version"))); diff --git a/src/test/fakes.rs b/src/test/fakes.rs index 998f96958..0894b5b24 100644 --- a/src/test/fakes.rs +++ b/src/test/fakes.rs @@ -182,7 +182,7 @@ impl<'a> FakeRelease<'a> { self.has_docs, self.has_examples, )?; - crate::db::add_build_into_database(&db.conn(), &release_id, &self.build_result)?; + crate::db::add_build_into_database(&db.conn(), release_id, &self.build_result)?; Ok(release_id) } diff --git a/src/utils/daemon.rs b/src/utils/daemon.rs index 65a1f3c32..acd684d88 100644 --- a/src/utils/daemon.rs +++ b/src/utils/daemon.rs @@ -27,11 +27,12 @@ use ::{ pub fn start_daemon(background: bool) { // first check required environment variables for v in ["CRATESFYI_PREFIX", - "CRATESFYI_PREFIX", "CRATESFYI_GITHUB_USERNAME", "CRATESFYI_GITHUB_ACCESSTOKEN"] .iter() { - env::var(v).expect(&format!("Environment variable {} not found", v)); + if env::var(v).is_err() { + panic!("Environment variable {} not found", v); + } } let dbopts = opts(); diff --git a/src/utils/github_updater.rs b/src/utils/github_updater.rs index c672c93f6..d6e4b264d 100644 --- a/src/utils/github_updater.rs +++ b/src/utils/github_updater.rs @@ -83,8 +83,7 @@ fn get_github_fields(path: &str) -> Result { .basic_auth( env::var("CRATESFYI_GITHUB_USERNAME") .ok() - .and_then(|u| Some(u.to_string())) - .unwrap_or("".to_string()), + .unwrap_or_default(), env::var("CRATESFYI_GITHUB_ACCESSTOKEN").ok(), ) .send()?; @@ -109,7 +108,7 @@ fn get_github_fields(path: &str) -> Result { .and_then(|d| d.as_string()) .unwrap_or(""), "%Y-%m-%dT%H:%M:%S") - .unwrap_or(time::now()) + .unwrap_or_else(|_| time::now()) .to_timespec(), }) } @@ -125,7 +124,7 @@ fn get_github_path(url: &str) -> Option { Some(format!("{}/{}", username, if reponame.ends_with(".git") { - reponame.split(".git").nth(0).unwrap() + reponame.split(".git").next().unwrap() } else { reponame })) diff --git a/src/utils/html.rs b/src/utils/html.rs index f0671e423..3d2e8c98a 100644 --- a/src/utils/html.rs +++ b/src/utils/html.rs @@ -23,8 +23,8 @@ fn extract_from_rcdom(dom: &RcDom) -> Result<(Handle, Handle)> { let (mut head, mut body) = (None, None); while let Some(handle) = worklist.pop() { - match handle.data { - NodeData::Element { ref name, .. } => match name.local.as_ref() { + if let NodeData::Element { ref name, .. } = handle.data { + match name.local.as_ref() { "head" => { if head.is_some() { return Err(err_msg("duplicate tag")); @@ -41,7 +41,6 @@ fn extract_from_rcdom(dom: &RcDom) -> Result<(Handle, Handle)> { } _ => {} // do nothing } - _ => {} // do nothing } worklist.extend(handle.children.borrow().iter().cloned()); diff --git a/src/web/builds.rs b/src/web/builds.rs index 80ee92ad9..b0ce00b1c 100644 --- a/src/web/builds.rs +++ b/src/web/builds.rs @@ -97,7 +97,7 @@ pub fn build_list_handler(req: &mut Request) -> IronResult { let id: i32 = row.get(5); let build = Build { - id: id, + id, rustc_version: row.get(6), cratesfyi_version: row.get(7), build_status: row.get(8), @@ -134,7 +134,7 @@ pub fn build_list_handler(req: &mut Request) -> IronResult { let builds_page = BuildsPage { metadata: MetaData::from_crate(&conn, &name, &version), builds: build_list, - build_details: build_details, + build_details, limits, }; Page::new(builds_page) diff --git a/src/web/crate_details.rs b/src/web/crate_details.rs index e4e4d9517..b400968a4 100644 --- a/src/web/crate_details.rs +++ b/src/web/crate_details.rs @@ -146,7 +146,7 @@ impl CrateDetails { let rows = conn.query(query, &[&name, &version]).unwrap(); - if rows.len() == 0 { + if rows.is_empty() { return None; } @@ -158,15 +158,15 @@ impl CrateDetails { let mut versions: Vec = Vec::new(); let versions_from_db: Json = rows.get(0).get(17); - versions_from_db.as_array().map(|vers| { + if let Some(vers) = versions_from_db.as_array() { for version in vers { - version.as_string().map(|version| { + if let Some(version) = version.as_string() { if let Ok(sem_ver) = semver::Version::parse(&version) { versions.push(sem_ver); }; - }); + }; } - }); + }; versions.sort(); versions.reverse(); @@ -206,7 +206,7 @@ impl CrateDetails { github_stars: rows.get(0).get(18), github_forks: rows.get(0).get(19), github_issues: rows.get(0).get(20), - metadata: metadata, + metadata, is_library: rows.get(0).get(21), doc_targets: rows.get(0).get(22), license: rows.get(0).get(23), diff --git a/src/web/mod.rs b/src/web/mod.rs index 5bd6e5945..9a2e9ef38 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -70,10 +70,10 @@ use std::sync::{Arc, Mutex}; /// Duration of static files for staticfile and DatabaseFileHandler (in seconds) const STATIC_FILE_CACHE_DURATION: u64 = 60 * 60 * 24 * 30 * 12; // 12 months -const STYLE_CSS: &'static str = include_str!(concat!(env!("OUT_DIR"), "/style.css")); -const MENU_JS: &'static str = include_str!(concat!(env!("OUT_DIR"), "/menu.js")); -const INDEX_JS: &'static str = include_str!(concat!(env!("OUT_DIR"), "/index.js")); -const OPENSEARCH_XML: &'static [u8] = include_bytes!("opensearch.xml"); +const STYLE_CSS: &str = include_str!(concat!(env!("OUT_DIR"), "/style.css")); +const MENU_JS: &str = include_str!(concat!(env!("OUT_DIR"), "/menu.js")); +const INDEX_JS: &str = include_str!(concat!(env!("OUT_DIR"), "/index.js")); +const OPENSEARCH_XML: &[u8] = include_bytes!("opensearch.xml"); const DEFAULT_BIND: &str = "0.0.0.0:3000"; @@ -209,10 +209,6 @@ impl MatchVersion { MatchVersion::None => None, } } - - fn strip_id(self) -> Option { - self.into_option().map(|(version, _id)| version) - } } /// Checks the database for crate releases that match the given name and version. @@ -226,19 +222,19 @@ fn match_version(conn: &Connection, name: &str, version: Option<&str>) -> MatchV use url::percent_encoding::percent_decode; let req_version = version.and_then(|v| { match percent_decode(v.as_bytes()).decode_utf8() { - Ok(p) => Some(p.into_owned()), + Ok(p) => Some(p), Err(_) => None, } }) - .map(|v| if v == "newest" || v == "latest" { "*".to_owned() } else { v }) - .unwrap_or("*".to_string()); + .map(|v| if v == "newest" || v == "latest" { "*".into() } else { v }) + .unwrap_or_else(|| "*".into()); let versions: Vec<(String, i32)> = { let query = "SELECT version, releases.id FROM releases INNER JOIN crates ON releases.crate_id = crates.id WHERE name = $1 AND yanked = false"; let rows = conn.query(query, &[&name]).unwrap(); - if rows.len() == 0 { + if rows.is_empty() { return MatchVersion::None; } rows.iter().map(|row| (row.get(0), row.get(1))).collect() @@ -322,7 +318,7 @@ pub struct Server { impl Server { pub fn start(addr: Option<&str>) -> Self { - let server = Self::start_inner(addr.unwrap_or(DEFAULT_BIND), Box::new(|| Pool::new())); + let server = Self::start_inner(addr.unwrap_or(DEFAULT_BIND), Box::new(Pool::new)); info!("Running docs.rs web server on http://{}", server.addr()); server } @@ -475,7 +471,7 @@ pub(crate) struct MetaData { impl MetaData { fn from_crate(conn: &Connection, name: &str, version: &str) -> Option { - for row in &conn.query("SELECT crates.name, + if let Some(row) = &conn.query("SELECT crates.name, releases.version, releases.description, releases.target_name, @@ -485,7 +481,7 @@ impl MetaData { INNER JOIN crates ON crates.id = releases.crate_id WHERE crates.name = $1 AND releases.version = $2", &[&name, &version]) - .unwrap() { + .unwrap().iter().next() { return Some(MetaData { name: row.get(0), @@ -522,6 +518,12 @@ mod test { use html5ever::tendril::TendrilSink; use crate::web::{match_version, MatchVersion}; + impl MatchVersion { + fn strip_id(self) -> Option { + self.into_option().map(|(version, _id)| version) + } + } + const DEFAULT_ID: i32 = 0; fn release(version: &str, db: &TestDatabase) -> i32 { diff --git a/src/web/page.rs b/src/web/page.rs index 983d96c46..634e3f36f 100644 --- a/src/web/page.rs +++ b/src/web/page.rs @@ -62,7 +62,7 @@ impl Page { pub fn new(content: T) -> Page { Page { title: None, - content: content, + content, status: status::Ok, varss: BTreeMap::new(), varsb: BTreeMap::new(), @@ -73,28 +73,28 @@ impl Page { /// Sets a string variable pub fn set(mut self, var: &str, val: &str) -> Page { - &self.varss.insert(var.to_owned(), val.to_owned()); + self.varss.insert(var.to_owned(), val.to_owned()); self } /// Sets a boolean variable pub fn set_bool(mut self, var: &str, val: bool) -> Page { - &self.varsb.insert(var.to_owned(), val); + self.varsb.insert(var.to_owned(), val); self } /// Sets a boolean variable to true pub fn set_true(mut self, var: &str) -> Page { - &self.varsb.insert(var.to_owned(), true); + self.varsb.insert(var.to_owned(), true); self } /// Sets an integer variable pub fn set_int(mut self, var: &str, val: i64) -> Page { - &self.varsi.insert(var.to_owned(), val); + self.varsi.insert(var.to_owned(), val); self } @@ -113,6 +113,7 @@ impl Page { } + #[allow(clippy::wrong_self_convention)] pub fn to_resp(self, template: &str) -> IronResult { let mut resp = Response::new(); let status = self.status; diff --git a/src/web/pool.rs b/src/web/pool.rs index 1f4cbdf4e..d611c2c13 100644 --- a/src/web/pool.rs +++ b/src/web/pool.rs @@ -46,7 +46,7 @@ pub(crate) enum PoolConnection { } impl PoolConnection { - pub(super) fn get<'a>(&'a self) -> DerefConnection<'a> { + pub(super) fn get(&self) -> DerefConnection<'_> { match self { Self::R2D2(conn) => DerefConnection::Connection(&conn), #[cfg(test)] diff --git a/src/web/releases.rs b/src/web/releases.rs index 53bf13cc7..493cc652d 100644 --- a/src/web/releases.rs +++ b/src/web/releases.rs @@ -397,11 +397,13 @@ pub fn author_handler(req: &mut Request) -> IronResult { let page_number: i64 = router.find("page").unwrap_or("1").parse().unwrap_or(1); let conn = extension!(req, Pool).get(); + + #[allow(clippy::or_fun_call)] let author = ctry!(router.find("author") .ok_or(IronError::new(Nope::CrateNotFound, status::NotFound))); - let (author_name, packages) = if author.starts_with("@") { - let mut author = author.clone().split("@"); + let (author_name, packages) = if author.starts_with('@') { + let mut author = author.split('@'); get_releases_by_owner(&conn, page_number, RELEASES_IN_RELEASES, @@ -519,6 +521,7 @@ pub fn search_handler(req: &mut Request) -> IronResult { let search_query = query.replace(" ", " & "); + #[allow(clippy::or_fun_call)] get_search_results(&conn, &search_query, 1, RELEASES_IN_RELEASES) .ok_or(IronError::new(Nope::NoResults, status::NotFound)) .and_then(|(_, results)| { diff --git a/src/web/routes.rs b/src/web/routes.rs index b3dec0d49..7a7401f07 100644 --- a/src/web/routes.rs +++ b/src/web/routes.rs @@ -197,7 +197,7 @@ impl Routes { if !pattern.ends_with('/') { let pattern = format!("{}/", pattern); self.get.push(( - pattern.to_string(), + pattern, Box::new(SimpleRedirect::new(|url| { url.set_path(&url.path().trim_end_matches('/').to_string()) })), diff --git a/src/web/rustdoc.rs b/src/web/rustdoc.rs index de7637e22..588dd6447 100644 --- a/src/web/rustdoc.rs +++ b/src/web/rustdoc.rs @@ -374,7 +374,7 @@ pub fn badge_handler(req: &mut Request) -> IronResult { FROM releases WHERE releases.id = $1", &[&id])); - if rows.len() > 0 && rows.get(0).get(0) { + if !rows.is_empty() && rows.get(0).get(0) { BadgeOptions { subject: "docs".to_owned(), status: version, diff --git a/src/web/source.rs b/src/web/source.rs index 44eaf13d2..0ed496fe5 100644 --- a/src/web/source.rs +++ b/src/web/source.rs @@ -101,7 +101,7 @@ impl FileList { &[&name, &version]) .unwrap(); - if rows.len() == 0 { + if rows.is_empty() { return None; } @@ -109,22 +109,22 @@ impl FileList { let mut file_list: Vec = Vec::new(); - files.as_array().map(|files| { + if let Some(files) = files.as_array() { for file in files { - file.as_array().map(|file| { + if let Some(file) = file.as_array() { let mime = file[0].as_string().unwrap(); let path = file[1].as_string().unwrap(); // skip .cargo-ok generated by cargo if path == ".cargo-ok" { - return; + continue; } // look only files for req_path if path.starts_with(&req_path) { // remove req_path from path to reach files in this directory let path = path.replace(&req_path, ""); - let path_splited: Vec<&str> = path.split("/").collect(); + let path_splited: Vec<&str> = path.split('/').collect(); // if path have '/' it is a directory let ftype = if path_splited.len() > 1 { @@ -148,9 +148,9 @@ impl FileList { file_list.push(file); } } - }); + }; } - }); + }; if file_list.is_empty() { return None; @@ -198,11 +198,11 @@ pub fn source_browser_handler(req: &mut Request) -> IronResult { // FileList::from_path is only working for directories // remove file name if it's not a directory - req_path.last_mut().map(|last| { + if let Some(last) = req_path.last_mut() { if !last.is_empty() { *last = ""; } - }); + } // remove crate name and version from req_path let path = req_path.join("/").replace(&format!("{}/{}/", name, version), ""); @@ -215,7 +215,7 @@ pub fn source_browser_handler(req: &mut Request) -> IronResult { // try to get actual file first // skip if request is a directory - let file = if !file_path.ends_with("/") { + let file = if !file_path.ends_with('/') { DbFile::from_path(&conn, &file_path) } else { None