Skip to content
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ name = "rustcast"
version = "0.5.2"
edition = "2024"

[lints.rustdoc]
missing_docs = "warn"


[target.'cfg(target_os = "windows")'.dependencies]
winreg = "0.52"
windows = { version = "0.58", features = [
Expand Down
19 changes: 9 additions & 10 deletions src/app/apps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,23 +83,22 @@ pub struct App {
pub desc: String,

/// The information specific to a certain type of app
pub app_data: AppData,
pub data: AppData,

/// A unique ID generated for each instance of an App.
///
/// This is made by atomically incrementing a counter every time a new instance of the struct
/// is made. The implementation of [`PartialEq`] uses this.
#[allow(unused)]
id: usize,
}

impl PartialEq for App {
fn eq(&self, other: &Self) -> bool {
self.app_data == other.app_data && self.name == other.name
self.data == other.data && self.name == other.name
}
}

impl App {
/// Get the internal id
/// Get the numeric id of an app
#[allow(unused)]
pub fn id(&self) -> usize {
self.id
}
Expand All @@ -113,7 +112,7 @@ impl App {
name: name.to_string(),
desc: desc.to_string(),
id: ID.fetch_add(1, Ordering::Relaxed),
app_data: data,
data,
}
}

Expand Down Expand Up @@ -248,7 +247,7 @@ impl App {
.height(50);

if theme.show_icons {
match self.app_data {
match self.data {
AppData::Command {
icon: Some(ref icon),
..
Expand Down Expand Up @@ -280,7 +279,7 @@ impl App {
}
row = row.push(container(text_block).width(Fill));

let msg = match self.app_data {
let msg = match self.data {
AppData::Builtin {
command: AppCommand::Function(func),
..
Expand Down Expand Up @@ -309,7 +308,7 @@ impl App {
.height(50);

container(content)
.id(format!("result-{}", id_num))
.id(format!("result-{id_num}"))
.style(move |_| result_row_container_style(&theme, focused))
.padding(8)
.width(Fill)
Expand Down
10 changes: 5 additions & 5 deletions src/app/menubar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub fn menu_icon(#[cfg(not(target_os = "linux"))] hotkey: HotKey, sender: ExtSen

let menu = Menu::with_items(&[
&version_item(),
&about_item(image),
&about_item(&image),
&open_github_item(),
&PredefinedMenuItem::separator(),
&refresh_item(),
Expand Down Expand Up @@ -97,7 +97,7 @@ fn init_event_handler(sender: ExtSender) {
}
"open_issue_page" => {
if let Err(e) = open::that("https://github.com/unsecretised/rustcast/issues/new") {
tracing::error!("Error opening url: {}", e)
tracing::error!("Error opening url: {}", e);
}
}
"show_rustcast" => {
Expand All @@ -112,15 +112,15 @@ fn init_event_handler(sender: ExtSender) {
if let Err(e) = open::that(
"https://github.com/unsecretised/rustcast/discussions/new?category=q-a",
) {
tracing::error!("Error opening url: {}", e)
tracing::error!("Error opening url: {}", e);
}
}
"open_preferences" => {
open_settings();
}
"open_github_page" => {
if let Err(e) = open::that("https://github.com/unsecretised/rustcast") {
tracing::error!("Error opening url: {}", e)
tracing::error!("Error opening url: {}", e);
}
}
_ => {}
Expand Down Expand Up @@ -196,7 +196,7 @@ fn quit_item() -> PredefinedMenuItem {
PredefinedMenuItem::quit(Some("Quit"))
}

fn about_item(image: DynamicImage) -> PredefinedMenuItem {
fn about_item(image: &DynamicImage) -> PredefinedMenuItem {
let about_metadata_builder = AboutMetadataBuilder::new()
.name(Some("RustCast"))
.version(Some(
Expand Down
20 changes: 13 additions & 7 deletions src/app/pages/clipboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,26 @@ use iced::widget::{
use crate::{app::pages::prelude::*, clipboard::ClipBoardContentType};

pub fn clipboard_view(
clipboard_content: Vec<ClipBoardContentType>,
clipboard_content: &[ClipBoardContentType],
focussed_id: u32,
theme: Theme,
theme: &Theme,
focus_id: u32,
) -> Element<'static, Message> {
let theme_clone = theme.clone();
let theme_clone_2 = theme.clone();
container(Row::from_vec(vec![
container(
scrollable(
Column::from_iter(clipboard_content.iter().enumerate().map(|(i, content)| {
content.to_app().render(theme.clone(), i as u32, focus_id)
}))
.width(WINDOW_WIDTH / 3.),
clipboard_content
.iter()
.enumerate()
.map(|(i, content)| {
// I'd be surprised if you get 4 billion entries
#[allow(clippy::cast_possible_truncation)]
content.to_app().render(theme.clone(), i as u32, focus_id)
})
.collect::<Column<_>>()
.width(WINDOW_WIDTH / 3.),
)
.id("results"),
)
Expand All @@ -31,7 +37,7 @@ pub fn clipboard_view(
clipboard_content
.get(focussed_id as usize)
.map(|x| x.to_app().alias)
.unwrap_or("".to_string()),
.unwrap_or_default(),
)
.height(385)
.width(Length::Fill)
Expand Down
6 changes: 3 additions & 3 deletions src/app/pages/emoji.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use crate::{app::pages::prelude::*, clipboard::ClipBoardContentType, commands::F

pub fn emoji_page(
tile_theme: Theme,
emojis: Vec<App>,
emojis: &[App],
focussed_id: u32,
) -> Element<'static, Message> {
let emoji_vec = emojis
.chunks(6)
.map(|x| x.to_vec())
.map(<[App]>::to_vec)
.collect::<Vec<Vec<App>>>();

let mut column = Vec::new();
Expand Down Expand Up @@ -43,7 +43,7 @@ pub fn emoji_page(
)
.width(70)
.height(70)
.id(format!("result-{}", id_num))
.id(format!("result-{id_num}"))
.style(move |_| emoji_button_container_style(&theme_clone, focussed_id == id_num)),
container(
Text::new(emoji.desc)
Expand Down
58 changes: 30 additions & 28 deletions src/app/tile/elm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@ use iced::{Length::Fill, widget::text_input};

use rayon::slice::ParallelSliceMut;

#[cfg(target_os = "windows")]
use crate::app;
use crate::app::WINDOW_WIDTH;
use crate::app::pages::clipboard::clipboard_view;
use crate::app::pages::emoji::emoji_page;
use crate::app::tile::AppIndex;
use crate::app_finding::index_installed_apps;
use crate::config::Theme;
use crate::styles::{contents_style, rustcast_text_input_style, tint, with_alpha};
use crate::utils::index_installed_apps;
use crate::{
app::{Message, Page, apps::App, default_settings, tile::Tile},
config::Config,
Expand Down Expand Up @@ -77,7 +75,7 @@ pub fn new(
config: &Config,
) -> (Tile, Task<Message>) {
tracing::trace!(target: "elm_init", "Initing ELM");

#[allow(unused_mut)]
let mut settings = default_settings();

Expand All @@ -92,7 +90,7 @@ pub fn new(
}

tracing::trace!(target: "elm_init", "Opening window");

// id unused on windows, but not macos
#[allow(unused)]
let (id, open) = window::open(settings);
Expand All @@ -115,13 +113,13 @@ pub fn new(
let options = index_installed_apps(config);

if let Err(ref e) = options {
tracing::error!("Error indexing apps: {e}")
tracing::error!("Error indexing apps: {e}");
}

// Still try to load the rest
let mut options = options.unwrap_or_default();

options.extend(config.shells.iter().map(|x| x.to_app()));
options.extend(config.shells.iter().map(crate::config::Shelly::to_app));
options.extend(App::basic_apps());
options.par_sort_by_key(|x| x.name.len());
let options = AppIndex::from_apps(options);
Expand All @@ -137,7 +135,7 @@ pub fn new(
visible: true,
focused: false,
config: config.clone(),
theme: config.theme.to_owned().into(),
theme: config.theme.clone().into(),
clipboard_content: vec![],
tray_icon: None,
sender: None,
Expand All @@ -160,7 +158,7 @@ pub fn new(
clipboard_hotkey: config
.clipboard_hotkey
.clone()
.and_then(|x| x.parse::<HotKey>().ok()),
.and_then(|x: String| x.parse().ok()),
},
open,
)
Expand Down Expand Up @@ -196,36 +194,39 @@ pub fn view(tile: &Tile, wid: window::Id) -> Element<'_, Message> {

let results = if tile.page == Page::ClipboardHistory {
clipboard_view(
tile.clipboard_content.clone(),
&tile.clipboard_content,
tile.focus_id,
tile.config.theme.clone(),
&tile.config.theme,
tile.focus_id,
)
} else if tile.results.is_empty() {
space().into()
} else if tile.page == Page::EmojiSearch {
emoji_page(
tile.config.theme.clone(),
tile.emoji_apps
.search_prefix(&tile.query_lc)
.map(|x| x.to_owned())
.collect(),
tile.focus_id,
)
let results: Vec<_> = tile
.emoji_apps
.search_prefix(&tile.query_lc)
.map(std::borrow::ToOwned::to_owned)
.collect();

emoji_page(tile.config.theme.clone(), &results, tile.focus_id)
} else {
container(Column::from_iter(tile.results.iter().enumerate().map(
|(i, app)| {
app.clone()
.render(tile.config.theme.clone(), i as u32, tile.focus_id)
},
)))
container(
tile.results
.iter()
.enumerate()
.map(|(i, app)| {
#[allow(clippy::cast_possible_truncation)]
app.clone()
.render(tile.config.theme.clone(), i as u32, tile.focus_id)
})
.collect::<Column<_>>(),
)
.into()
};

let results_count = match &tile.page {
Page::Main => tile.results.len(),
Page::ClipboardHistory => tile.clipboard_content.len(),
Page::EmojiSearch => tile.results.len(),
Page::Main | Page::EmojiSearch => tile.results.len(),
};

let height = if tile.page == Page::ClipboardHistory {
Expand All @@ -234,6 +235,7 @@ pub fn view(tile: &Tile, wid: window::Id) -> Element<'_, Message> {
std::cmp::min(tile.results.len() * 60, 290)
};

#[allow(clippy::cast_possible_truncation)]
let scrollable = Scrollable::with_direction(results, scrollbar_direction)
.id("results")
.height(height as u32);
Expand Down Expand Up @@ -278,7 +280,7 @@ fn footer(theme: Theme, results_count: usize) -> Element<'static, Message> {
} else if results_count == 1 {
"1 result found"
} else {
&format!("{} results found", results_count)
&format!("{results_count} results found")
};

container(
Expand Down
21 changes: 10 additions & 11 deletions src/app/tile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ pub struct Tile {

impl Tile {
/// This returns the theme of the window
pub fn theme(&self, _: window::Id) -> Option<Theme> {
Some(self.theme.clone())
pub fn theme(&self, _: window::Id) -> Theme {
self.theme.clone()
}

/// This handles the subscriptions of the window
Expand Down Expand Up @@ -232,7 +232,7 @@ impl Tile {
};
let results: Vec<App> = options
.search_prefix(&query)
.map(|x| x.to_owned())
.map(std::borrow::ToOwned::to_owned)
.collect();

self.results = results;
Expand Down Expand Up @@ -292,9 +292,9 @@ impl Tile {
fn handle_hot_reloading() -> impl futures::Stream<Item = Message> {
stream::channel(100, async |mut output| {
let mut content = fs::read_to_string(
std::env::var("HOME").unwrap_or("".to_owned()) + "/.config/rustcast/config.toml",
std::env::var("HOME").unwrap_or_default() + "/.config/rustcast/config.toml",
)
.unwrap_or("".to_string());
.unwrap_or_default();

let paths = default_app_paths();
let mut total_files: usize = paths
Expand All @@ -304,9 +304,9 @@ fn handle_hot_reloading() -> impl futures::Stream<Item = Message> {

loop {
let current_content = fs::read_to_string(
std::env::var("HOME").unwrap_or("".to_owned()) + "/.config/rustcast/config.toml",
std::env::var("HOME").unwrap_or_default() + "/.config/rustcast/config.toml",
)
.unwrap_or("".to_string());
.unwrap_or_default();

let current_total_files: usize = paths
.par_iter()
Expand All @@ -328,13 +328,12 @@ fn handle_hot_reloading() -> impl futures::Stream<Item = Message> {

fn count_dirs_in_dir(dir: &PathBuf) -> usize {
// Read the directory; if it fails, treat as empty
let entries = match fs::read_dir(dir) {
Ok(e) => e,
Err(_) => return 0,
let Ok(entries) = fs::read_dir(dir) else {
return 0;
};

entries
.filter_map(|entry| entry.ok())
.filter_map(std::result::Result::ok)
.filter(|entry| entry.file_type().map(|t| t.is_dir()).unwrap_or(false))
.count()
}
Expand Down
Loading
Loading