Compare commits

...

2 Commits

Author SHA1 Message Date
ea6fa551a2 chore: Remove all unwraps from util.rs and add state_lock macro
Signed-off-by: quexeky <git@quexeky.dev>
2025-09-04 18:02:36 +10:00
be4fc2d37a fix: Add lint and remove all unwraps from lib.rs
Signed-off-by: quexeky <git@quexeky.dev>
2025-09-04 17:29:52 +10:00
4 changed files with 93 additions and 36 deletions

View File

@ -4,6 +4,7 @@
#![feature(duration_millis_float)] #![feature(duration_millis_float)]
#![feature(iterator_try_collect)] #![feature(iterator_try_collect)]
#![deny(clippy::all)] #![deny(clippy::all)]
#![deny(clippy::unwrap_used)]
mod database; mod database;
mod games; mod games;
@ -13,6 +14,7 @@ mod download_manager;
mod error; mod error;
mod process; mod process;
mod remote; mod remote;
mod utils;
use crate::database::scan::scan_install_dirs; use crate::database::scan::scan_install_dirs;
use crate::process::commands::open_process_logs; use crate::process::commands::open_process_logs;
@ -45,7 +47,7 @@ use games::commands::{
}; };
use games::downloads::commands::download_game; use games::downloads::commands::download_game;
use games::library::{Game, update_game_configuration}; use games::library::{Game, update_game_configuration};
use log::{LevelFilter, debug, info, warn}; use log::{LevelFilter, debug, info, warn, error};
use log4rs::Config; use log4rs::Config;
use log4rs::append::console::ConsoleAppender; use log4rs::append::console::ConsoleAppender;
use log4rs::append::file::FileAppender; use log4rs::append::file::FileAppender;
@ -137,7 +139,7 @@ async fn setup(handle: AppHandle) -> AppState<'static> {
))) )))
.append(false) .append(false)
.build(DATA_ROOT_DIR.join("./drop.log")) .build(DATA_ROOT_DIR.join("./drop.log"))
.unwrap(); .expect("Failed to setup logfile");
let console = ConsoleAppender::builder() let console = ConsoleAppender::builder()
.encoder(Box::new(PatternEncoder::new( .encoder(Box::new(PatternEncoder::new(
@ -157,9 +159,9 @@ async fn setup(handle: AppHandle) -> AppState<'static> {
.appenders(vec!["logfile", "console"]) .appenders(vec!["logfile", "console"])
.build(LevelFilter::from_str(&log_level).expect("Invalid log level")), .build(LevelFilter::from_str(&log_level).expect("Invalid log level")),
) )
.unwrap(); .expect("Failed to build config");
log4rs::init_config(config).unwrap(); log4rs::init_config(config).expect("Failed to initialise log4rs");
let games = HashMap::new(); let games = HashMap::new();
let download_manager = Arc::new(DownloadManagerBuilder::build(handle.clone())); let download_manager = Arc::new(DownloadManagerBuilder::build(handle.clone()));
@ -370,42 +372,57 @@ pub fn run() {
.shadow(false) .shadow(false)
.data_directory(DATA_ROOT_DIR.join(".webview")) .data_directory(DATA_ROOT_DIR.join(".webview"))
.build() .build()
.unwrap(); .expect("Failed to build main window");
app.deep_link().on_open_url(move |event| { app.deep_link().on_open_url(move |event| {
debug!("handling drop:// url"); debug!("handling drop:// url");
let binding = event.urls(); let binding = event.urls();
let url = binding.first().unwrap(); let url = match binding.first() {
if url.host_str().unwrap() == "handshake" { Some(url) => url,
None => {
warn!("No value recieved from deep link. Is this a drop server?");
return;
}
};
if let Some("handshake") = url.host_str() {
tauri::async_runtime::spawn(recieve_handshake( tauri::async_runtime::spawn(recieve_handshake(
handle.clone(), handle.clone(),
url.path().to_string(), url.path().to_string(),
)); ));
} }
}); });
let open_menu_item = MenuItem::with_id(app, "open", "Open", true, None::<&str>).expect("Failed to generate open menu item");
let sep = PredefinedMenuItem::separator(app).expect("Failed to generate menu separator item");
let quit_menu_item = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>).expect("Failed to generate quit menu item");
let menu = Menu::with_items( let menu = Menu::with_items(
app, app,
&[ &[
&MenuItem::with_id(app, "open", "Open", true, None::<&str>).unwrap(), &open_menu_item,
&PredefinedMenuItem::separator(app).unwrap(), &sep,
/* /*
&MenuItem::with_id(app, "show_library", "Library", true, None::<&str>)?, &MenuItem::with_id(app, "show_library", "Library", true, None::<&str>)?,
&MenuItem::with_id(app, "show_settings", "Settings", true, None::<&str>)?, &MenuItem::with_id(app, "show_settings", "Settings", true, None::<&str>)?,
&PredefinedMenuItem::separator(app)?, &PredefinedMenuItem::separator(app)?,
*/ */
&MenuItem::with_id(app, "quit", "Quit", true, None::<&str>).unwrap(), &quit_menu_item,
], ],
) )
.unwrap(); .expect("Failed to generate menu");
run_on_tray(|| { run_on_tray(|| {
TrayIconBuilder::new() TrayIconBuilder::new()
.icon(app.default_window_icon().unwrap().clone()) .icon(app.default_window_icon().expect("Failed to get default window icon").clone())
.menu(&menu) .menu(&menu)
.on_menu_event(|app, event| match event.id.as_ref() { .on_menu_event(|app, event| match event.id.as_ref() {
"open" => { "open" => {
app.webview_windows().get("main").unwrap().show().unwrap(); app.webview_windows()
.get("main")
.expect("Failed to get webview")
.show()
.expect("Failed to show window");
} }
"quit" => { "quit" => {
cleanup_and_exit(app, &app.state()); cleanup_and_exit(app, &app.state());
@ -422,15 +439,19 @@ pub fn run() {
{ {
let mut db_handle = borrow_db_mut_checked(); let mut db_handle = borrow_db_mut_checked();
if let Some(original) = db_handle.prev_database.take() { if let Some(original) = db_handle.prev_database.take() {
let canonicalised = match original.canonicalize() {
Ok(o) => o,
Err(_) => original,
};
warn!( warn!(
"Database corrupted. Original file at {}", "Database corrupted. Original file at {}",
original.canonicalize().unwrap().to_string_lossy() canonicalised.display()
); );
app.dialog() app.dialog()
.message( .message(format!(
"Database corrupted. A copy has been saved at: ".to_string() "Database corrupted. A copy has been saved at: {}",
+ original.to_str().unwrap(), canonicalised.display()
) ))
.title("Database corrupted") .title("Database corrupted")
.show(|_| {}); .show(|_| {});
} }
@ -463,7 +484,7 @@ pub fn run() {
.on_window_event(|window, event| { .on_window_event(|window, event| {
if let WindowEvent::CloseRequested { api, .. } = event { if let WindowEvent::CloseRequested { api, .. } = event {
run_on_tray(|| { run_on_tray(|| {
window.hide().unwrap(); window.hide().expect("Failed to close window in tray");
api.prevent_close(); api.prevent_close();
}); });
} }

View File

@ -14,6 +14,7 @@ use crate::{
AppState, AppStatus, AppState, AppStatus,
database::db::{DATA_ROOT_DIR, borrow_db_mut_checked}, database::db::{DATA_ROOT_DIR, borrow_db_mut_checked},
error::remote_access_error::RemoteAccessError, error::remote_access_error::RemoteAccessError,
state_lock,
}; };
#[derive(Deserialize)] #[derive(Deserialize)]
@ -37,17 +38,41 @@ fn fetch_certificates() -> Vec<Certificate> {
match entry { match entry {
Ok(c) => { Ok(c) => {
let mut buf = Vec::new(); let mut buf = Vec::new();
File::open(c.path()).unwrap().read_to_end(&mut buf).unwrap(); match File::open(c.path()) {
Ok(f) => f,
Err(e) => {
warn!(
"Failed to open file at {} with error {}",
c.path().display(),
e
);
continue;
}
}
.read_to_end(&mut buf)
.expect(&format!(
"Failed to read to end of certificate file {}",
c.path().display()
));
for cert in Certificate::from_pem_bundle(&buf).unwrap() { match Certificate::from_pem_bundle(&buf) {
Ok(certificates) => {
for cert in certificates {
certs.push(cert); certs.push(cert);
} }
info!( info!(
"added {} certificate(s) from {}", "added {} certificate(s) from {}",
certs.len(), certs.len(),
c.file_name().into_string().unwrap() c.file_name().display()
); );
} }
Err(e) => warn!(
"Invalid certificate file {} with error {}",
c.path().display(),
e
),
}
}
Err(_) => todo!(), Err(_) => todo!(),
} }
} }
@ -65,7 +90,7 @@ pub fn get_client_sync() -> reqwest::blocking::Client {
for cert in DROP_CERT_BUNDLE.iter() { for cert in DROP_CERT_BUNDLE.iter() {
client = client.add_root_certificate(cert.clone()); client = client.add_root_certificate(cert.clone());
} }
client.use_rustls_tls().build().unwrap() client.use_rustls_tls().build().expect("Failed to build synchronous client")
} }
pub fn get_client_async() -> reqwest::Client { pub fn get_client_async() -> reqwest::Client {
let mut client = reqwest::ClientBuilder::new(); let mut client = reqwest::ClientBuilder::new();
@ -73,7 +98,7 @@ pub fn get_client_async() -> reqwest::Client {
for cert in DROP_CERT_BUNDLE.iter() { for cert in DROP_CERT_BUNDLE.iter() {
client = client.add_root_certificate(cert.clone()); client = client.add_root_certificate(cert.clone());
} }
client.use_rustls_tls().build().unwrap() client.use_rustls_tls().build().expect("Failed to build asynchronous client")
} }
pub fn get_client_ws() -> reqwest::Client { pub fn get_client_ws() -> reqwest::Client {
let mut client = reqwest::ClientBuilder::new(); let mut client = reqwest::ClientBuilder::new();
@ -81,7 +106,11 @@ pub fn get_client_ws() -> reqwest::Client {
for cert in DROP_CERT_BUNDLE.iter() { for cert in DROP_CERT_BUNDLE.iter() {
client = client.add_root_certificate(cert.clone()); client = client.add_root_certificate(cert.clone());
} }
client.use_rustls_tls().http1_only().build().unwrap() client
.use_rustls_tls()
.http1_only()
.build()
.expect("Failed to build websocket client")
} }
pub async fn use_remote_logic( pub async fn use_remote_logic(
@ -107,7 +136,7 @@ pub async fn use_remote_logic(
return Err(RemoteAccessError::InvalidEndpoint); return Err(RemoteAccessError::InvalidEndpoint);
} }
let mut app_state = state.lock().unwrap(); let mut app_state = state_lock!(state);
app_state.status = AppStatus::SignedOut; app_state.status = AppStatus::SignedOut;
drop(app_state); drop(app_state);

View File

@ -0,0 +1 @@
pub mod state_lock;

View File

@ -0,0 +1,6 @@
#[macro_export]
macro_rules! state_lock {
($state:expr) => {
$state.lock().expect("Failed to lock onto state")
};
}