perf: optimise tab::folder_name

This was done by separating out the function to get the display name
into its own function, then running just that.
This commit is contained in:
Cheong Lau 2025-10-28 17:13:22 +10:00
parent 7cc28a9b68
commit 2eaad6088a

View file

@ -583,6 +583,36 @@ pub fn fs_kind(_metadata: &Metadata) -> FsKind {
FsKind::Local
}
fn get_desktop_file_display_name(path: &Path) -> Option<String> {
let entry = match freedesktop_entry_parser::parse_entry(path) {
Ok(ok) => ok,
Err(err) => {
log::warn!("failed to parse {}: {}", path.display(), err);
return None;
}
};
entry
.section("Desktop Entry")
.attr("Name")
.map(str::to_string)
}
fn get_desktop_file_icon(path: &Path) -> Option<String> {
let entry = match freedesktop_entry_parser::parse_entry(path) {
Ok(ok) => ok,
Err(err) => {
log::warn!("failed to parse {}: {}", path.display(), err);
return None;
}
};
entry
.section("Desktop Entry")
.attr("Icon")
.map(str::to_string)
}
pub fn parse_desktop_file(path: &Path) -> (Option<String>, Option<String>) {
let entry = match freedesktop_entry_parser::parse_entry(path) {
Ok(ok) => ok,
@ -591,25 +621,33 @@ pub fn parse_desktop_file(path: &Path) -> (Option<String>, Option<String>) {
return (None, None);
}
};
let section = entry.section("Desktop Entry");
(
entry
.section("Desktop Entry")
.attr("Name")
.map(|x| x.to_string()),
entry
.section("Desktop Entry")
.attr("Icon")
.map(|x| x.to_string()),
section.attr("Name").map(str::to_string),
section.attr("Icon").map(str::to_string),
)
}
fn display_name_for_file(path: &Path, name: &str, get_from_gvfs: bool, is_desktop: bool) -> String {
if is_desktop {
get_desktop_file_display_name(path).map_or_else(
|| Item::display_name(name),
|desktop_name| Item::display_name(desktop_name.as_str()),
)
} else if get_from_gvfs {
Item::display_name(glib::filename_display_name(path).as_str())
} else {
Item::display_name(name)
}
}
#[cfg(feature = "gvfs")]
pub fn item_from_gvfs_info(path: PathBuf, file_info: gio::FileInfo, sizes: IconSizes) -> Item {
let file_name = file_info
.attribute_as_string(gio::FILE_ATTRIBUTE_STANDARD_NAME)
.unwrap_or_default();
let mtime = file_info.attribute_uint64(gio::FILE_ATTRIBUTE_TIME_MODIFIED);
let mut display_name = Item::display_name(&file_info.display_name());
let mut is_desktop = false;
let remote = file_info.boolean(gio::FILE_ATTRIBUTE_FILESYSTEM_REMOTE);
let is_dir = matches!(file_info.file_type(), gio::FileType::Directory);
@ -633,11 +671,8 @@ pub fn item_from_gvfs_info(path: PathBuf, file_info: gio::FileInfo, sizes: IconS
//TODO: clean this up, implement for trash
let icon_name_opt = if mime == "application/x-desktop" {
let (desktop_name_opt, icon_name_opt) = parse_desktop_file(&path);
if let Some(desktop_name) = desktop_name_opt {
display_name = Item::display_name(&desktop_name);
}
icon_name_opt
is_desktop = true;
get_desktop_file_icon(&path)
} else {
None
};
@ -679,6 +714,8 @@ pub fn item_from_gvfs_info(path: PathBuf, file_info: gio::FileInfo, sizes: IconS
}
}
let display_name = display_name_for_file(&path, &file_info.display_name(), false, is_desktop);
Item {
name: file_name.clone().to_string(),
display_name,
@ -716,7 +753,8 @@ pub fn item_from_entry(
metadata: fs::Metadata,
sizes: IconSizes,
) -> Item {
let mut display_name = Item::display_name(&name);
let mut is_desktop = false;
let mut is_gvfs = false;
let hidden = name.starts_with(".") || hidden_attribute(&metadata);
@ -725,20 +763,8 @@ pub fn item_from_entry(
FsKind::Remote => true,
#[cfg(feature = "gvfs")]
FsKind::Gvfs => {
is_gvfs = true;
let file = gio::File::for_path(&path);
match gio::prelude::FileExt::query_info(
&file,
gio::FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
gio::FileQueryInfoFlags::NONE,
gio::Cancellable::NONE,
) {
Ok(info) => {
display_name = Item::display_name(&info.display_name());
}
Err(err) => {
log::warn!("failed to get GIO info for {:?}: {}", path, err);
}
}
match gio::prelude::FileExt::query_filesystem_info(
&file,
@ -775,11 +801,8 @@ pub fn item_from_entry(
let mime = mime_for_path(&path, Some(&metadata), remote);
//TODO: clean this up, implement for trash
let icon_name_opt = if mime == "application/x-desktop" {
let (desktop_name_opt, icon_name_opt) = parse_desktop_file(&path);
if let Some(desktop_name) = desktop_name_opt {
display_name = Item::display_name(&desktop_name);
}
icon_name_opt
is_desktop = true;
get_desktop_file_icon(&path)
} else {
None
};
@ -821,6 +844,8 @@ pub fn item_from_entry(
}
}
let display_name = display_name_for_file(&path, &name, is_gvfs, is_desktop);
Item {
name,
display_name,
@ -851,9 +876,8 @@ pub fn item_from_entry(
}
}
pub fn item_from_path<P: Into<PathBuf>>(path: P, sizes: IconSizes) -> Result<Item, String> {
let path = path.into();
let name = match path.file_name() {
fn get_filename_from_path(path: &Path) -> Result<String, String> {
Ok(match path.file_name() {
Some(name_os) => name_os
.to_str()
.ok_or_else(|| {
@ -864,7 +888,12 @@ pub fn item_from_path<P: Into<PathBuf>>(path: P, sizes: IconSizes) -> Result<Ite
})?
.to_string(),
None => fl!("filesystem"),
};
})
}
pub fn item_from_path<P: Into<PathBuf>>(path: P, sizes: IconSizes) -> Result<Item, String> {
let path = path.into();
let name = get_filename_from_path(&path)?;
let metadata = fs::metadata(&path)
.map_err(|err| format!("failed to read metadata for {:?}: {}", path, err))?;
Ok(item_from_entry(path, name, metadata, sizes))
@ -2488,10 +2517,12 @@ fn folder_name<P: AsRef<Path>>(path: P) -> (String, bool) {
found_home = true;
fl!("home")
} else {
// This is not optimized but it helps ensure the same display names
match item_from_path(path, IconSizes::default()) {
Ok(item) => item.display_name,
Err(_err) => name.to_string_lossy().to_string(),
match (get_filename_from_path(path), fs::metadata(path)) {
(Ok(name), Ok(metadata)) => {
let is_gvfs = fs_kind(&metadata) == FsKind::Gvfs;
display_name_for_file(path, &name, is_gvfs, false)
}
_ => name.to_string_lossy().to_string(),
}
}
}