lots of clippy lints

This commit is contained in:
Conrad Ludgate 2022-04-24 22:19:30 +01:00
parent 1c591b223d
commit 1234da033f
20 changed files with 90 additions and 63 deletions

View File

@ -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<Path>) -> Result<Self> {
let path = path.as_ref();
debug!("opening sqlite database at {:?}", path);
pub async fn new(path: impl AsRef<Path> + Sync + Send) -> Result<Self> {
async fn inner(path: &Path) -> Result<Sqlite> {
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(),

View File

@ -29,7 +29,7 @@ pub fn new_key(settings: &Settings) -> Result<secretbox::Key> {
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<String> {
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<String> {
}
}
pub fn encode_key(key: secretbox::Key) -> Result<String> {
pub fn encode_key(key: &secretbox::Key) -> Result<String> {
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);
}
}

View File

@ -46,7 +46,7 @@ impl History {
}
}
pub fn success(&self) -> bool {
pub const fn success(&self) -> bool {
self.exit == 0 || self.duration == -1
}
}

View File

@ -45,7 +45,7 @@ impl<R: Read> Fish<R> {
impl Importer for Fish<File> {
const NAME: &'static str = "fish";
/// see https://fishshell.com/docs/current/interactive.html#searchable-command-history
/// see <https://fishshell.com/docs/current/interactive.html#searchable-command-history>
fn histpath() -> Result<PathBuf> {
let base = BaseDirs::new().ok_or_else(|| eyre!("could not determine data directory"))?;
let data = base.data_local_dir();

View File

@ -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::<ReshEntry>(&self.strbuf) {
let entry = match serde_json::from_str::<Entry>(&self.strbuf) {
Ok(e) => e,
Err(e) if e.is_eof() => return None,
Err(e) => {

View File

@ -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;

View File

@ -9,14 +9,14 @@ pub fn reorder_fuzzy(mode: SearchMode, query: &str, res: Vec<History>) -> Vec<Hi
}
}
fn reorder<F, A>(query: &str, f: F, res: Vec<A>) -> Vec<A>
fn reorder<F, A>(query: &str, f: F, mut res: Vec<A>) -> Vec<A>
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
}

View File

@ -49,10 +49,10 @@ pub enum Dialect {
}
impl From<Dialect> 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::<Self>()
.map_err(|e| eyre!("failed to deserialize: {}", e))?;
// all paths should be expanded

View File

@ -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,

View File

@ -1,4 +1,6 @@
#![forbid(unsafe_code)]
#![warn(clippy::pedantic, clippy::nursery)]
#![allow(clippy::must_use_candidate)]
pub mod api;
pub mod utils;

View File

@ -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?;

View File

@ -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};

View File

@ -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,

View File

@ -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;

View File

@ -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::<IpAddr>()?;
let postgres = Postgres::new(settings.db_uri.as_str())

View File

@ -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))

View File

@ -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<Event<Key>, crossbeam_channel::RecvError> {

View File

@ -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
}
}
}

View File

@ -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(())
}

View File

@ -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;