1
1
mirror of https://github.com/ellie/atuin.git synced 2024-08-18 01:10:37 +03:00

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 { Context {
session, session,
hostname,
cwd, cwd,
hostname,
} }
} }
@ -86,26 +86,28 @@ pub struct Sqlite {
} }
impl Sqlite { impl Sqlite {
pub async fn new(path: impl AsRef<Path>) -> Result<Self> { pub async fn new(path: impl AsRef<Path> + Sync + Send) -> Result<Self> {
let path = path.as_ref(); async fn inner(path: &Path) -> Result<Sqlite> {
debug!("opening sqlite database at {:?}", path); debug!("opening sqlite database at {:?}", path);
let create = !path.exists(); let create = !path.exists();
if create { if create {
if let Some(dir) = path.parent() { if let Some(dir) = path.parent() {
fs::create_dir_all(dir)?; 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 })
} }
inner(path.as_ref()).await
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 })
} }
async fn setup_db(pool: &SqlitePool) -> Result<()> { async fn setup_db(pool: &SqlitePool) -> Result<()> {
@ -135,6 +137,7 @@ impl Sqlite {
Ok(()) Ok(())
} }
#[allow(clippy::needless_pass_by_value)]
fn query_history(row: SqliteRow) -> History { fn query_history(row: SqliteRow) -> History {
History { History {
id: row.get("id"), id: row.get("id"),
@ -167,7 +170,7 @@ impl Database for Sqlite {
let mut tx = self.pool.begin().await?; let mut tx = self.pool.begin().await?;
for i in h { for i in h {
Self::save_raw(&mut tx, i).await? Self::save_raw(&mut tx, i).await?;
} }
tx.commit().await?; tx.commit().await?;
@ -366,9 +369,8 @@ impl Database for Sqlite {
if !is_or { if !is_or {
is_or = true; is_or = true;
continue; continue;
} else {
format!("{glob}|{glob}")
} }
format!("{glob}|{glob}")
} else if let Some(term) = query_part.strip_prefix('^') { } else if let Some(term) = query_part.strip_prefix('^') {
format!("{term}{glob}") format!("{term}{glob}")
} else if let Some(term) = query_part.strip_suffix('$') { } else if let Some(term) = query_part.strip_suffix('$') {
@ -414,7 +416,7 @@ mod test {
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
async fn assert_search_eq<'a>( async fn assert_search_eq<'a>(
db: &impl Database, db: &(impl Database + Sync + Send),
mode: SearchMode, mode: SearchMode,
filter_mode: FilterMode, filter_mode: FilterMode,
query: &str, query: &str,
@ -439,7 +441,7 @@ mod test {
} }
async fn assert_search_commands( async fn assert_search_commands(
db: &impl Database, db: &(impl Database + Sync + Send),
mode: SearchMode, mode: SearchMode,
filter_mode: FilterMode, filter_mode: FilterMode,
query: &str, query: &str,
@ -452,7 +454,7 @@ mod test {
assert_eq!(commands, expected_commands); 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( let history = History::new(
chrono::Utc::now(), chrono::Utc::now(),
cmd.to_string(), 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 path = settings.key_path.as_str();
let key = secretbox::gen_key(); let key = secretbox::gen_key();
let encoded = encode_key(key.clone())?; let encoded = encode_key(&key)?;
let mut file = fs::File::create(path)?; let mut file = fs::File::create(path)?;
file.write_all(encoded.as_bytes())?; file.write_all(encoded.as_bytes())?;
@ -59,7 +59,7 @@ pub fn load_encoded_key(settings: &Settings) -> Result<String> {
Ok(key) Ok(key)
} else { } else {
let key = secretbox::gen_key(); let key = secretbox::gen_key();
let encoded = encode_key(key)?; let encoded = encode_key(&key)?;
let mut file = fs::File::create(path)?; let mut file = fs::File::create(path)?;
file.write_all(encoded.as_bytes())?; 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 = rmp_serde::to_vec(&key).wrap_err("could not encode key to message pack")?;
let buf = base64::encode(buf); let buf = base64::encode(buf);
@ -140,6 +140,7 @@ mod test {
}; };
// this should err // 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 self.exit == 0 || self.duration == -1
} }
} }

View File

@ -45,7 +45,7 @@ impl<R: Read> Fish<R> {
impl Importer for Fish<File> { impl Importer for Fish<File> {
const NAME: &'static str = "fish"; 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> { fn histpath() -> Result<PathBuf> {
let base = BaseDirs::new().ok_or_else(|| eyre!("could not determine data directory"))?; let base = BaseDirs::new().ok_or_else(|| eyre!("could not determine data directory"))?;
let data = base.data_local_dir(); let data = base.data_local_dir();

View File

@ -15,7 +15,7 @@ use crate::history::History;
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ReshEntry { pub struct Entry {
pub cmd_line: String, pub cmd_line: String,
pub exit_code: i64, pub exit_code: i64,
pub shell: String, 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 // .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. // 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. // 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, Ok(e) => e,
Err(e) if e.is_eof() => return None, Err(e) if e.is_eof() => return None,
Err(e) => { Err(e) => {

View File

@ -1,4 +1,11 @@
#![forbid(unsafe_code)] #![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] #[macro_use]
extern crate log; 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 where
F: Fn(&A) -> &String, F: Fn(&A) -> &String,
A: Clone, A: Clone,
{ {
let mut r = res.clone();
let qvec = &query.chars().collect(); 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 // TODO for fzf search we should sum up scores for each matched term
let (from, to) = match minspan::span(qvec, &(f(h).chars().collect())) { let (from, to) = match minspan::span(qvec, &(f(h).chars().collect())) {
Some(x) => x, 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 // 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 // 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. // possible legitimate match. This is meaningless except as a comparison.
None => (0, res.len()), None => (0, len),
}; };
1 + to - from 1 + to - from
}); });
r res
} }

View File

@ -49,10 +49,10 @@ pub enum Dialect {
} }
impl From<Dialect> for chrono_english::Dialect { impl From<Dialect> for chrono_english::Dialect {
fn from(d: Dialect) -> chrono_english::Dialect { fn from(d: Dialect) -> Self {
match d { match d {
Dialect::Uk => chrono_english::Dialect::Uk, Dialect::Uk => Self::Uk,
Dialect::Us => chrono_english::Dialect::Us, Dialect::Us => Self::Us,
} }
} }
} }
@ -124,7 +124,7 @@ impl Settings {
match parse(self.sync_frequency.as_str()) { match parse(self.sync_frequency.as_str()) {
Ok(d) => { Ok(d) => {
let d = chrono::Duration::from_std(d).unwrap(); 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)), Err(e) => Err(eyre!("failed to check sync: {}", e)),
} }
@ -187,8 +187,8 @@ impl Settings {
}; };
let config = config_builder.build()?; let config = config_builder.build()?;
let mut settings: Settings = config let mut settings = config
.try_deserialize() .try_deserialize::<Self>()
.map_err(|e| eyre!("failed to deserialize: {}", e))?; .map_err(|e| eyre!("failed to deserialize: {}", e))?;
// all paths should be expanded // all paths should be expanded

View File

@ -31,7 +31,7 @@ pub fn hash_str(string: &str) -> String {
async fn sync_download( async fn sync_download(
force: bool, force: bool,
client: &api_client::Client<'_>, client: &api_client::Client<'_>,
db: &mut (impl Database + Send), db: &mut (impl Database + Send + Sync),
) -> Result<(i64, i64)> { ) -> Result<(i64, i64)> {
debug!("starting sync download"); debug!("starting sync download");
@ -87,7 +87,7 @@ async fn sync_upload(
settings: &Settings, settings: &Settings,
_force: bool, _force: bool,
client: &api_client::Client<'_>, client: &api_client::Client<'_>,
db: &mut (impl Database + Send), db: &mut (impl Database + Send + Sync),
) -> Result<()> { ) -> Result<()> {
debug!("starting sync upload"); debug!("starting sync upload");
@ -137,7 +137,7 @@ async fn sync_upload(
Ok(()) 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( let client = api_client::Client::new(
&settings.sync_address, &settings.sync_address,
&settings.session_token, &settings.session_token,

View File

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

View File

@ -354,7 +354,7 @@ impl Database for Postgres {
// All the years we need to get data for // All the years we need to get data for
// The upper bound is exclusive, so include current +1 // The upper bound is exclusive, so include current +1
let years = oldest..current_year + 1; let years = oldest..=current_year;
for year in years { for year in years {
let count = self.count_history_year(user, year).await?; 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::database::{Database, Postgres};
use crate::models::{NewHistory, User}; use crate::models::{NewHistory, User};
use atuin_common::api::*; use atuin_common::api::{
AddHistoryRequest, CountResponse, SyncHistoryRequest, SyncHistoryResponse,
};
use crate::calendar::{TimePeriod, TimePeriodInfo}; use crate::calendar::{TimePeriod, TimePeriodInfo};

View File

@ -26,7 +26,7 @@ pub struct ErrorResponseStatus<'a> {
} }
impl<'a> ErrorResponse<'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 { ErrorResponseStatus {
error: self, error: self,
status, status,

View File

@ -1,6 +1,8 @@
use std::borrow::Borrow; use std::borrow::Borrow;
use atuin_common::api::*; use atuin_common::api::{
LoginRequest, LoginResponse, RegisterRequest, RegisterResponse, UserResponse,
};
use axum::extract::Path; use axum::extract::Path;
use axum::{Extension, Json}; use axum::{Extension, Json};
use http::StatusCode; use http::StatusCode;
@ -15,8 +17,6 @@ use crate::settings::Settings;
use super::{ErrorResponse, ErrorResponseStatus}; use super::{ErrorResponse, ErrorResponseStatus};
pub fn verify_str(secret: &str, verify: &str) -> bool { pub fn verify_str(secret: &str, verify: &str) -> bool {
sodiumoxide::init().unwrap();
let mut padded = [0_u8; 128]; let mut padded = [0_u8; 128];
secret.as_bytes().iter().enumerate().for_each(|(i, val)| { secret.as_bytes().iter().enumerate().for_each(|(i, val)| {
padded[i] = *val; padded[i] = *val;

View File

@ -1,4 +1,14 @@
#![forbid(unsafe_code)] #![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}; use std::net::{IpAddr, SocketAddr};
@ -17,6 +27,8 @@ pub mod router;
pub mod settings; pub mod settings;
pub async fn launch(settings: Settings, host: String, port: u16) -> Result<()> { pub async fn launch(settings: Settings, host: String, port: u16) -> Result<()> {
sodiumoxide::init().unwrap();
let host = host.parse::<IpAddr>()?; let host = host.parse::<IpAddr>()?;
let postgres = Postgres::new(settings.db_uri.as_str()) let postgres = Postgres::new(settings.db_uri.as_str())

View File

@ -56,6 +56,7 @@ where
async fn teapot() -> impl IntoResponse { async fn teapot() -> impl IntoResponse {
(http::StatusCode::IM_A_TEAPOT, "") (http::StatusCode::IM_A_TEAPOT, "")
} }
pub fn router(postgres: Postgres, settings: Settings) -> Router { pub fn router(postgres: Postgres, settings: Settings) -> Router {
Router::new() Router::new()
.route("/", get(handlers::index)) .route("/", get(handlers::index))

View File

@ -23,8 +23,8 @@ pub struct Config {
} }
impl Default for Config { impl Default for Config {
fn default() -> Config { fn default() -> Self {
Config { Self {
exit_key: Key::Char('q'), exit_key: Key::Char('q'),
tick_rate: Duration::from_millis(250), tick_rate: Duration::from_millis(250),
} }
@ -32,11 +32,11 @@ impl Default for Config {
} }
impl Events { impl Events {
pub fn new() -> Events { pub fn new() -> Self {
Events::with_config(Config::default()) Self::with_config(Config::default())
} }
pub fn with_config(config: Config) -> Events { pub fn with_config(config: Config) -> Self {
let (tx, rx) = unbounded(); let (tx, rx) = unbounded();
{ {
@ -59,7 +59,7 @@ impl Events {
thread::sleep(config.tick_rate); thread::sleep(config.tick_rate);
}); });
Events { rx } Self { rx }
} }
pub fn next(&self) -> Result<Event<Key>, crossbeam_channel::RecvError> { pub fn next(&self) -> Result<Event<Key>, crossbeam_channel::RecvError> {

View File

@ -62,11 +62,11 @@ pub enum ListMode {
impl ListMode { impl ListMode {
pub const fn from_flags(human: bool, cmd_only: bool) -> Self { pub const fn from_flags(human: bool, cmd_only: bool) -> Self {
if human { if human {
ListMode::Human Self::Human
} else if cmd_only { } else if cmd_only {
ListMode::CmdOnly Self::CmdOnly
} else { } else {
ListMode::Regular Self::Regular
} }
} }
} }

View File

@ -45,7 +45,7 @@ impl Cmd {
Self::Key => { Self::Key => {
use atuin_client::encryption::{encode_key, load_key}; use atuin_client::encryption::{encode_key, load_key};
let key = load_key(&settings).wrap_err("could not load encryption 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); println!("{}", encode);
Ok(()) Ok(())
} }

View File

@ -1,5 +1,5 @@
#![forbid(unsafe_code)]
#![warn(clippy::pedantic, clippy::nursery)] #![warn(clippy::pedantic, clippy::nursery)]
#![allow(clippy::use_self)] // not 100% reliable
use clap::AppSettings; use clap::AppSettings;
use clap::Parser; use clap::Parser;