From 1234da033f8cc31044547feb91e09dea540123ad Mon Sep 17 00:00:00 2001 From: Conrad Ludgate Date: Sun, 24 Apr 2022 22:19:30 +0100 Subject: [PATCH] lots of clippy lints --- atuin-client/src/database.rs | 50 +++++++++++++++------------- atuin-client/src/encryption.rs | 9 ++--- atuin-client/src/history.rs | 2 +- atuin-client/src/import/fish.rs | 2 +- atuin-client/src/import/resh.rs | 4 +-- atuin-client/src/lib.rs | 7 ++++ atuin-client/src/ordering.rs | 10 +++--- atuin-client/src/settings.rs | 12 +++---- atuin-client/src/sync.rs | 6 ++-- atuin-common/src/lib.rs | 2 ++ atuin-server/src/database.rs | 2 +- atuin-server/src/handlers/history.rs | 4 ++- atuin-server/src/handlers/mod.rs | 2 +- atuin-server/src/handlers/user.rs | 6 ++-- atuin-server/src/lib.rs | 12 +++++++ atuin-server/src/router.rs | 1 + src/command/client/event.rs | 12 +++---- src/command/client/history.rs | 6 ++-- src/command/client/sync.rs | 2 +- src/main.rs | 2 +- 20 files changed, 90 insertions(+), 63 deletions(-) diff --git a/atuin-client/src/database.rs b/atuin-client/src/database.rs index 14f01cd3..d2ca7edc 100644 --- a/atuin-client/src/database.rs +++ b/atuin-client/src/database.rs @@ -36,8 +36,8 @@ pub fn current_context() -> Context { Context { session, - hostname, cwd, + hostname, } } @@ -86,26 +86,28 @@ pub struct Sqlite { } impl Sqlite { - pub async fn new(path: impl AsRef) -> Result { - let path = path.as_ref(); - debug!("opening sqlite database at {:?}", path); + pub async fn new(path: impl AsRef + Sync + Send) -> Result { + async fn inner(path: &Path) -> Result { + debug!("opening sqlite database at {:?}", path); - let create = !path.exists(); - if create { - if let Some(dir) = path.parent() { - fs::create_dir_all(dir)?; + let create = !path.exists(); + if create { + if let Some(dir) = path.parent() { + fs::create_dir_all(dir)?; + } } + + let opts = SqliteConnectOptions::from_str(path.as_os_str().to_str().unwrap())? + .journal_mode(SqliteJournalMode::Wal) + .create_if_missing(true); + + let pool = SqlitePoolOptions::new().connect_with(opts).await?; + + Sqlite::setup_db(&pool).await?; + + Ok(Sqlite { pool }) } - - let opts = SqliteConnectOptions::from_str(path.as_os_str().to_str().unwrap())? - .journal_mode(SqliteJournalMode::Wal) - .create_if_missing(true); - - let pool = SqlitePoolOptions::new().connect_with(opts).await?; - - Self::setup_db(&pool).await?; - - Ok(Self { pool }) + inner(path.as_ref()).await } async fn setup_db(pool: &SqlitePool) -> Result<()> { @@ -135,6 +137,7 @@ impl Sqlite { Ok(()) } + #[allow(clippy::needless_pass_by_value)] fn query_history(row: SqliteRow) -> History { History { id: row.get("id"), @@ -167,7 +170,7 @@ impl Database for Sqlite { let mut tx = self.pool.begin().await?; for i in h { - Self::save_raw(&mut tx, i).await? + Self::save_raw(&mut tx, i).await?; } tx.commit().await?; @@ -366,9 +369,8 @@ impl Database for Sqlite { if !is_or { is_or = true; continue; - } else { - format!("{glob}|{glob}") } + format!("{glob}|{glob}") } else if let Some(term) = query_part.strip_prefix('^') { format!("{term}{glob}") } else if let Some(term) = query_part.strip_suffix('$') { @@ -414,7 +416,7 @@ mod test { use std::time::{Duration, Instant}; async fn assert_search_eq<'a>( - db: &impl Database, + db: &(impl Database + Sync + Send), mode: SearchMode, filter_mode: FilterMode, query: &str, @@ -439,7 +441,7 @@ mod test { } async fn assert_search_commands( - db: &impl Database, + db: &(impl Database + Sync + Send), mode: SearchMode, filter_mode: FilterMode, query: &str, @@ -452,7 +454,7 @@ mod test { assert_eq!(commands, expected_commands); } - async fn new_history_item(db: &mut impl Database, cmd: &str) -> Result<()> { + async fn new_history_item(db: &mut (impl Database + Sync + Send), cmd: &str) -> Result<()> { let history = History::new( chrono::Utc::now(), cmd.to_string(), diff --git a/atuin-client/src/encryption.rs b/atuin-client/src/encryption.rs index f805cbd5..ca5dac04 100644 --- a/atuin-client/src/encryption.rs +++ b/atuin-client/src/encryption.rs @@ -29,7 +29,7 @@ pub fn new_key(settings: &Settings) -> Result { let path = settings.key_path.as_str(); let key = secretbox::gen_key(); - let encoded = encode_key(key.clone())?; + let encoded = encode_key(&key)?; let mut file = fs::File::create(path)?; file.write_all(encoded.as_bytes())?; @@ -59,7 +59,7 @@ pub fn load_encoded_key(settings: &Settings) -> Result { Ok(key) } else { let key = secretbox::gen_key(); - let encoded = encode_key(key)?; + let encoded = encode_key(&key)?; let mut file = fs::File::create(path)?; file.write_all(encoded.as_bytes())?; @@ -68,7 +68,7 @@ pub fn load_encoded_key(settings: &Settings) -> Result { } } -pub fn encode_key(key: secretbox::Key) -> Result { +pub fn encode_key(key: &secretbox::Key) -> Result { let buf = rmp_serde::to_vec(&key).wrap_err("could not encode key to message pack")?; let buf = base64::encode(buf); @@ -140,6 +140,7 @@ mod test { }; // this should err - let _ = decrypt(&e2, &key1).expect_err("expected an error decrypting with invalid key"); + let err = decrypt(&e2, &key1).expect_err("expected an error decrypting with invalid key"); + drop(err); } } diff --git a/atuin-client/src/history.rs b/atuin-client/src/history.rs index c7bf6111..1fa7962d 100644 --- a/atuin-client/src/history.rs +++ b/atuin-client/src/history.rs @@ -46,7 +46,7 @@ impl History { } } - pub fn success(&self) -> bool { + pub const fn success(&self) -> bool { self.exit == 0 || self.duration == -1 } } diff --git a/atuin-client/src/import/fish.rs b/atuin-client/src/import/fish.rs index 70639264..542c64e0 100644 --- a/atuin-client/src/import/fish.rs +++ b/atuin-client/src/import/fish.rs @@ -45,7 +45,7 @@ impl Fish { impl Importer for Fish { const NAME: &'static str = "fish"; - /// see https://fishshell.com/docs/current/interactive.html#searchable-command-history + /// see fn histpath() -> Result { let base = BaseDirs::new().ok_or_else(|| eyre!("could not determine data directory"))?; let data = base.data_local_dir(); diff --git a/atuin-client/src/import/resh.rs b/atuin-client/src/import/resh.rs index cd5dccf7..41d0f61f 100644 --- a/atuin-client/src/import/resh.rs +++ b/atuin-client/src/import/resh.rs @@ -15,7 +15,7 @@ use crate::history::History; #[derive(Deserialize, Debug)] #[serde(rename_all = "camelCase")] -pub struct ReshEntry { +pub struct Entry { pub cmd_line: String, pub exit_code: i64, pub shell: String, @@ -113,7 +113,7 @@ impl Iterator for Resh { // .resh_history.json lies about being a json. It is actually a file containing valid json // on every line. This means that the last line will throw an error, as it is just an EOF. // Without the special case here, that will crash the importer. - let entry = match serde_json::from_str::(&self.strbuf) { + let entry = match serde_json::from_str::(&self.strbuf) { Ok(e) => e, Err(e) if e.is_eof() => return None, Err(e) => { diff --git a/atuin-client/src/lib.rs b/atuin-client/src/lib.rs index 497c5e74..a7d3e5a8 100644 --- a/atuin-client/src/lib.rs +++ b/atuin-client/src/lib.rs @@ -1,4 +1,11 @@ #![forbid(unsafe_code)] +#![warn(clippy::pedantic, clippy::nursery)] +#![allow( + clippy::missing_panics_doc, + clippy::missing_errors_doc, + clippy::must_use_candidate, + clippy::unreadable_literal +)] #[macro_use] extern crate log; diff --git a/atuin-client/src/ordering.rs b/atuin-client/src/ordering.rs index 0bb12c6a..3136834c 100644 --- a/atuin-client/src/ordering.rs +++ b/atuin-client/src/ordering.rs @@ -9,14 +9,14 @@ pub fn reorder_fuzzy(mode: SearchMode, query: &str, res: Vec) -> Vec(query: &str, f: F, res: Vec) -> Vec +fn reorder(query: &str, f: F, mut res: Vec) -> Vec where F: Fn(&A) -> &String, A: Clone, { - let mut r = res.clone(); let qvec = &query.chars().collect(); - r.sort_by_cached_key(|h| { + let len = res.len(); + res.sort_by_cached_key(|h| { // TODO for fzf search we should sum up scores for each matched term let (from, to) = match minspan::span(qvec, &(f(h).chars().collect())) { Some(x) => x, @@ -24,9 +24,9 @@ where // we don't want to return a None, as the comparison behaviour would put the worst matches // at the front. therefore, we'll return a set of indices that are one larger than the longest // possible legitimate match. This is meaningless except as a comparison. - None => (0, res.len()), + None => (0, len), }; 1 + to - from }); - r + res } diff --git a/atuin-client/src/settings.rs b/atuin-client/src/settings.rs index bb3424a4..15b1c7e0 100644 --- a/atuin-client/src/settings.rs +++ b/atuin-client/src/settings.rs @@ -49,10 +49,10 @@ pub enum Dialect { } impl From for chrono_english::Dialect { - fn from(d: Dialect) -> chrono_english::Dialect { + fn from(d: Dialect) -> Self { match d { - Dialect::Uk => chrono_english::Dialect::Uk, - Dialect::Us => chrono_english::Dialect::Us, + Dialect::Uk => Self::Uk, + Dialect::Us => Self::Us, } } } @@ -124,7 +124,7 @@ impl Settings { match parse(self.sync_frequency.as_str()) { Ok(d) => { let d = chrono::Duration::from_std(d).unwrap(); - Ok(Utc::now() - Settings::last_sync()? >= d) + Ok(Utc::now() - Self::last_sync()? >= d) } Err(e) => Err(eyre!("failed to check sync: {}", e)), } @@ -187,8 +187,8 @@ impl Settings { }; let config = config_builder.build()?; - let mut settings: Settings = config - .try_deserialize() + let mut settings = config + .try_deserialize::() .map_err(|e| eyre!("failed to deserialize: {}", e))?; // all paths should be expanded diff --git a/atuin-client/src/sync.rs b/atuin-client/src/sync.rs index 23f552e5..8a97de42 100644 --- a/atuin-client/src/sync.rs +++ b/atuin-client/src/sync.rs @@ -31,7 +31,7 @@ pub fn hash_str(string: &str) -> String { async fn sync_download( force: bool, client: &api_client::Client<'_>, - db: &mut (impl Database + Send), + db: &mut (impl Database + Send + Sync), ) -> Result<(i64, i64)> { debug!("starting sync download"); @@ -87,7 +87,7 @@ async fn sync_upload( settings: &Settings, _force: bool, client: &api_client::Client<'_>, - db: &mut (impl Database + Send), + db: &mut (impl Database + Send + Sync), ) -> Result<()> { debug!("starting sync upload"); @@ -137,7 +137,7 @@ async fn sync_upload( Ok(()) } -pub async fn sync(settings: &Settings, force: bool, db: &mut (impl Database + Send)) -> Result<()> { +pub async fn sync(settings: &Settings, force: bool, db: &mut (impl Database + Send + Sync)) -> Result<()> { let client = api_client::Client::new( &settings.sync_address, &settings.session_token, diff --git a/atuin-common/src/lib.rs b/atuin-common/src/lib.rs index e76a7abb..a5b6c406 100644 --- a/atuin-common/src/lib.rs +++ b/atuin-common/src/lib.rs @@ -1,4 +1,6 @@ #![forbid(unsafe_code)] +#![warn(clippy::pedantic, clippy::nursery)] +#![allow(clippy::must_use_candidate)] pub mod api; pub mod utils; diff --git a/atuin-server/src/database.rs b/atuin-server/src/database.rs index 2d3f8be1..f6f35ce6 100644 --- a/atuin-server/src/database.rs +++ b/atuin-server/src/database.rs @@ -354,7 +354,7 @@ impl Database for Postgres { // All the years we need to get data for // The upper bound is exclusive, so include current +1 - let years = oldest..current_year + 1; + let years = oldest..=current_year; for year in years { let count = self.count_history_year(user, year).await?; diff --git a/atuin-server/src/handlers/history.rs b/atuin-server/src/handlers/history.rs index aca9ecc6..fb16d845 100644 --- a/atuin-server/src/handlers/history.rs +++ b/atuin-server/src/handlers/history.rs @@ -6,7 +6,9 @@ use tracing::{debug, error, instrument}; use crate::database::{Database, Postgres}; use crate::models::{NewHistory, User}; -use atuin_common::api::*; +use atuin_common::api::{ + AddHistoryRequest, CountResponse, SyncHistoryRequest, SyncHistoryResponse, +}; use crate::calendar::{TimePeriod, TimePeriodInfo}; diff --git a/atuin-server/src/handlers/mod.rs b/atuin-server/src/handlers/mod.rs index 9e6659e2..7d1c3adc 100644 --- a/atuin-server/src/handlers/mod.rs +++ b/atuin-server/src/handlers/mod.rs @@ -26,7 +26,7 @@ pub struct ErrorResponseStatus<'a> { } impl<'a> ErrorResponse<'a> { - pub fn with_status(self, status: http::StatusCode) -> ErrorResponseStatus<'a> { + pub const fn with_status(self, status: http::StatusCode) -> ErrorResponseStatus<'a> { ErrorResponseStatus { error: self, status, diff --git a/atuin-server/src/handlers/user.rs b/atuin-server/src/handlers/user.rs index a57269a0..35ca3812 100644 --- a/atuin-server/src/handlers/user.rs +++ b/atuin-server/src/handlers/user.rs @@ -1,6 +1,8 @@ use std::borrow::Borrow; -use atuin_common::api::*; +use atuin_common::api::{ + LoginRequest, LoginResponse, RegisterRequest, RegisterResponse, UserResponse, +}; use axum::extract::Path; use axum::{Extension, Json}; use http::StatusCode; @@ -15,8 +17,6 @@ use crate::settings::Settings; use super::{ErrorResponse, ErrorResponseStatus}; pub fn verify_str(secret: &str, verify: &str) -> bool { - sodiumoxide::init().unwrap(); - let mut padded = [0_u8; 128]; secret.as_bytes().iter().enumerate().for_each(|(i, val)| { padded[i] = *val; diff --git a/atuin-server/src/lib.rs b/atuin-server/src/lib.rs index 7be54e58..f8344284 100644 --- a/atuin-server/src/lib.rs +++ b/atuin-server/src/lib.rs @@ -1,4 +1,14 @@ #![forbid(unsafe_code)] +#![warn(clippy::pedantic, clippy::nursery)] +#![allow( + clippy::missing_panics_doc, + clippy::missing_errors_doc, + clippy::unused_async, + clippy::must_use_candidate, + clippy::cast_sign_loss, + clippy::cast_lossless, + clippy::cast_possible_truncation +)] use std::net::{IpAddr, SocketAddr}; @@ -17,6 +27,8 @@ pub mod router; pub mod settings; pub async fn launch(settings: Settings, host: String, port: u16) -> Result<()> { + sodiumoxide::init().unwrap(); + let host = host.parse::()?; let postgres = Postgres::new(settings.db_uri.as_str()) diff --git a/atuin-server/src/router.rs b/atuin-server/src/router.rs index 9b525e05..8ba30999 100644 --- a/atuin-server/src/router.rs +++ b/atuin-server/src/router.rs @@ -56,6 +56,7 @@ where async fn teapot() -> impl IntoResponse { (http::StatusCode::IM_A_TEAPOT, "☕") } + pub fn router(postgres: Postgres, settings: Settings) -> Router { Router::new() .route("/", get(handlers::index)) diff --git a/src/command/client/event.rs b/src/command/client/event.rs index f09752d6..e6b1d9c8 100644 --- a/src/command/client/event.rs +++ b/src/command/client/event.rs @@ -23,8 +23,8 @@ pub struct Config { } impl Default for Config { - fn default() -> Config { - Config { + fn default() -> Self { + Self { exit_key: Key::Char('q'), tick_rate: Duration::from_millis(250), } @@ -32,11 +32,11 @@ impl Default for Config { } impl Events { - pub fn new() -> Events { - Events::with_config(Config::default()) + pub fn new() -> Self { + Self::with_config(Config::default()) } - pub fn with_config(config: Config) -> Events { + pub fn with_config(config: Config) -> Self { let (tx, rx) = unbounded(); { @@ -59,7 +59,7 @@ impl Events { thread::sleep(config.tick_rate); }); - Events { rx } + Self { rx } } pub fn next(&self) -> Result, crossbeam_channel::RecvError> { diff --git a/src/command/client/history.rs b/src/command/client/history.rs index 6e265e30..91b19105 100644 --- a/src/command/client/history.rs +++ b/src/command/client/history.rs @@ -62,11 +62,11 @@ pub enum ListMode { impl ListMode { pub const fn from_flags(human: bool, cmd_only: bool) -> Self { if human { - ListMode::Human + Self::Human } else if cmd_only { - ListMode::CmdOnly + Self::CmdOnly } else { - ListMode::Regular + Self::Regular } } } diff --git a/src/command/client/sync.rs b/src/command/client/sync.rs index 8e80310a..644e6633 100644 --- a/src/command/client/sync.rs +++ b/src/command/client/sync.rs @@ -45,7 +45,7 @@ impl Cmd { Self::Key => { use atuin_client::encryption::{encode_key, load_key}; let key = load_key(&settings).wrap_err("could not load encryption key")?; - let encode = encode_key(key).wrap_err("could not encode encryption key")?; + let encode = encode_key(&key).wrap_err("could not encode encryption key")?; println!("{}", encode); Ok(()) } diff --git a/src/main.rs b/src/main.rs index e5c81bbb..48e4db22 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ +#![forbid(unsafe_code)] #![warn(clippy::pedantic, clippy::nursery)] -#![allow(clippy::use_self)] // not 100% reliable use clap::AppSettings; use clap::Parser;