Skip to content

Commit 5d37420

Browse files
authored
feat: tauri command get_file_icon() (#756)
1 parent 1d3ceb0 commit 5d37420

4 files changed

Lines changed: 180 additions & 167 deletions

File tree

src-tauri/src/extension/built_in/file_search.rs

Lines changed: 2 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use tokio::io::BufReader;
2121
use tokio::process::Child;
2222
use tokio::process::Command;
2323
use tokio_stream::wrappers::LinesStream;
24+
use crate::util::file::get_file_icon;
2425

2526
pub(crate) const EXTENSION_ID: &str = "File Search";
2627

@@ -392,8 +393,7 @@ impl SearchSource for FileSearchExtensionSearchSource {
392393
let file_path =
393394
res_file_path.map_err(|io_err| SearchError::InternalError(io_err.to_string()))?;
394395

395-
let file_type = get_file_type(&file_path).await;
396-
let icon = type_to_icon(file_type);
396+
let icon = get_file_icon(file_path.clone()).await;
397397
let file_path_of_type_path = camino::Utf8Path::new(&file_path);
398398
let r#where = file_path_of_type_path
399399
.parent()
@@ -447,171 +447,6 @@ impl SearchSource for FileSearchExtensionSearchSource {
447447
}
448448
}
449449

450-
#[derive(Debug, Clone, PartialEq, Copy)]
451-
enum FileType {
452-
Folder,
453-
JPEGImage,
454-
PNGImage,
455-
PDFDocument,
456-
PlainTextDocument,
457-
MicrosoftWordDocument,
458-
MicrosoftExcelSpreadsheet,
459-
AudioFile,
460-
VideoFile,
461-
CHeaderFile,
462-
TOMLDocument,
463-
RustScript,
464-
CSourceCode,
465-
MarkdownDocument,
466-
TerminalSettings,
467-
ZipArchive,
468-
Dmg,
469-
Html,
470-
Json,
471-
Xml,
472-
Yaml,
473-
Css,
474-
Vue,
475-
React,
476-
Sql,
477-
Csv,
478-
Javascript,
479-
Typescript,
480-
Python,
481-
Java,
482-
Golang,
483-
Ruby,
484-
Php,
485-
Sass,
486-
Sketch,
487-
AdobeAi,
488-
AdobePsd,
489-
AdobePr,
490-
AdobeAu,
491-
AdobeAe,
492-
AdobeLr,
493-
AdobeXd,
494-
AdobeFl,
495-
AdobeId,
496-
Svg,
497-
Epub,
498-
Unknown,
499-
}
500-
501-
async fn get_file_type(path: &str) -> FileType {
502-
let path = camino::Utf8Path::new(path);
503-
504-
// stat() is more precise than file extension, use it if possible.
505-
if path.is_dir() {
506-
return FileType::Folder;
507-
}
508-
509-
let Some(ext) = path.extension() else {
510-
return FileType::Unknown;
511-
};
512-
513-
let ext = ext.to_lowercase();
514-
match ext.as_str() {
515-
"pdf" => FileType::PDFDocument,
516-
"txt" | "text" => FileType::PlainTextDocument,
517-
"doc" | "docx" => FileType::MicrosoftWordDocument,
518-
"xls" | "xlsx" => FileType::MicrosoftExcelSpreadsheet,
519-
"jpg" | "jpeg" => FileType::JPEGImage,
520-
"png" => FileType::PNGImage,
521-
"mp3" | "wav" | "flac" | "aac" | "ogg" | "m4a" => FileType::AudioFile,
522-
"mp4" | "avi" | "mov" | "mkv" | "wmv" | "flv" | "webm" => FileType::VideoFile,
523-
"h" | "hpp" => FileType::CHeaderFile,
524-
"c" | "cpp" | "cc" | "cxx" => FileType::CSourceCode,
525-
"toml" => FileType::TOMLDocument,
526-
"rs" => FileType::RustScript,
527-
"md" | "markdown" => FileType::MarkdownDocument,
528-
"terminal" => FileType::TerminalSettings,
529-
"zip" | "rar" | "7z" | "tar" | "gz" | "bz2" => FileType::ZipArchive,
530-
"dmg" => FileType::Dmg,
531-
"html" | "htm" => FileType::Html,
532-
"json" => FileType::Json,
533-
"xml" => FileType::Xml,
534-
"yaml" | "yml" => FileType::Yaml,
535-
"css" => FileType::Css,
536-
"vue" => FileType::Vue,
537-
"jsx" | "tsx" => FileType::React,
538-
"sql" => FileType::Sql,
539-
"csv" => FileType::Csv,
540-
"js" | "mjs" => FileType::Javascript,
541-
"ts" => FileType::Typescript,
542-
"py" | "pyw" => FileType::Python,
543-
"java" => FileType::Java,
544-
"go" => FileType::Golang,
545-
"rb" => FileType::Ruby,
546-
"php" => FileType::Php,
547-
"sass" | "scss" => FileType::Sass,
548-
"sketch" => FileType::Sketch,
549-
"ai" => FileType::AdobeAi,
550-
"psd" => FileType::AdobePsd,
551-
"prproj" => FileType::AdobePr,
552-
"aup" | "aup3" => FileType::AdobeAu,
553-
"aep" => FileType::AdobeAe,
554-
"lrcat" => FileType::AdobeLr,
555-
"xd" => FileType::AdobeXd,
556-
"fla" => FileType::AdobeFl,
557-
"indd" => FileType::AdobeId,
558-
"svg" => FileType::Svg,
559-
"epub" => FileType::Epub,
560-
_ => FileType::Unknown,
561-
}
562-
}
563-
564-
fn type_to_icon(ty: FileType) -> &'static str {
565-
match ty {
566-
FileType::Folder => "font_file_folder",
567-
FileType::JPEGImage => "font_file_image",
568-
FileType::PNGImage => "font_file_image",
569-
FileType::PDFDocument => "font_file_document_pdf",
570-
FileType::PlainTextDocument => "font_file_txt",
571-
FileType::MicrosoftWordDocument => "font_file_document_word",
572-
FileType::MicrosoftExcelSpreadsheet => "font_file_spreadsheet_excel",
573-
FileType::AudioFile => "font_file_audio",
574-
FileType::VideoFile => "font_file_video",
575-
FileType::CHeaderFile => "font_file_csource",
576-
FileType::TOMLDocument => "font_file_toml",
577-
FileType::RustScript => "font_file_rustscript1",
578-
FileType::CSourceCode => "font_file_csource",
579-
FileType::MarkdownDocument => "font_file_markdown",
580-
FileType::TerminalSettings => "font_file_terminal1",
581-
FileType::ZipArchive => "font_file_zip",
582-
FileType::Dmg => "font_file_dmg",
583-
FileType::Html => "font_file_html",
584-
FileType::Json => "font_file_json",
585-
FileType::Xml => "font_file_xml",
586-
FileType::Yaml => "font_file_yaml",
587-
FileType::Css => "font_file_css",
588-
FileType::Vue => "font_file_vue",
589-
FileType::React => "font_file_react",
590-
FileType::Sql => "font_file_sql",
591-
FileType::Csv => "font_file_csv",
592-
FileType::Javascript => "font_file_javascript",
593-
FileType::Typescript => "font_file_typescript",
594-
FileType::Python => "font_file_python",
595-
FileType::Java => "font_file_java",
596-
FileType::Golang => "font_file_golang",
597-
FileType::Ruby => "font_file_ruby",
598-
FileType::Php => "font_file_php",
599-
FileType::Sass => "font_file_sass",
600-
FileType::Sketch => "font_file_sketch",
601-
FileType::AdobeAi => "font_file_adobe_ai",
602-
FileType::AdobePsd => "font_file_adobe_psd",
603-
FileType::AdobePr => "font_file_adobe_pr",
604-
FileType::AdobeAu => "font_file_adobe_au",
605-
FileType::AdobeAe => "font_file_adobe_ae",
606-
FileType::AdobeLr => "font_file_adobe_lr",
607-
FileType::AdobeXd => "font_file_adobe_xd",
608-
FileType::AdobeFl => "font_file_adobe_fl",
609-
FileType::AdobeId => "font_file_adobe_id",
610-
FileType::Svg => "font_file_svg",
611-
FileType::Epub => "font_file_epub",
612-
FileType::Unknown => "font_file_unknown",
613-
}
614-
}
615450

616451
// Tauri commands for managing file system configuration
617452
#[tauri::command]

src-tauri/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ pub fn run() {
170170
#[cfg(target_os = "macos")]
171171
extension::built_in::file_search::set_file_system_config,
172172
server::synthesize::synthesize,
173+
util::file::get_file_icon,
173174
])
174175
.setup(|app| {
175176
#[cfg(target_os = "macos")]

src-tauri/src/util/file.rs

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
2+
#[derive(Debug, Clone, PartialEq, Copy)]
3+
pub(crate) enum FileType {
4+
Folder,
5+
JPEGImage,
6+
PNGImage,
7+
PDFDocument,
8+
PlainTextDocument,
9+
MicrosoftWordDocument,
10+
MicrosoftExcelSpreadsheet,
11+
AudioFile,
12+
VideoFile,
13+
CHeaderFile,
14+
TOMLDocument,
15+
RustScript,
16+
CSourceCode,
17+
MarkdownDocument,
18+
TerminalSettings,
19+
ZipArchive,
20+
Dmg,
21+
Html,
22+
Json,
23+
Xml,
24+
Yaml,
25+
Css,
26+
Vue,
27+
React,
28+
Sql,
29+
Csv,
30+
Javascript,
31+
Typescript,
32+
Python,
33+
Java,
34+
Golang,
35+
Ruby,
36+
Php,
37+
Sass,
38+
Sketch,
39+
AdobeAi,
40+
AdobePsd,
41+
AdobePr,
42+
AdobeAu,
43+
AdobeAe,
44+
AdobeLr,
45+
AdobeXd,
46+
AdobeFl,
47+
AdobeId,
48+
Svg,
49+
Epub,
50+
Unknown,
51+
}
52+
53+
54+
async fn get_file_type(path: &str) -> FileType {
55+
let path = camino::Utf8Path::new(path);
56+
57+
// stat() is more precise than file extension, use it if possible.
58+
if path.is_dir() {
59+
return FileType::Folder;
60+
}
61+
62+
let Some(ext) = path.extension() else {
63+
return FileType::Unknown;
64+
};
65+
66+
let ext = ext.to_lowercase();
67+
match ext.as_str() {
68+
"pdf" => FileType::PDFDocument,
69+
"txt" | "text" => FileType::PlainTextDocument,
70+
"doc" | "docx" => FileType::MicrosoftWordDocument,
71+
"xls" | "xlsx" => FileType::MicrosoftExcelSpreadsheet,
72+
"jpg" | "jpeg" => FileType::JPEGImage,
73+
"png" => FileType::PNGImage,
74+
"mp3" | "wav" | "flac" | "aac" | "ogg" | "m4a" => FileType::AudioFile,
75+
"mp4" | "avi" | "mov" | "mkv" | "wmv" | "flv" | "webm" => FileType::VideoFile,
76+
"h" | "hpp" => FileType::CHeaderFile,
77+
"c" | "cpp" | "cc" | "cxx" => FileType::CSourceCode,
78+
"toml" => FileType::TOMLDocument,
79+
"rs" => FileType::RustScript,
80+
"md" | "markdown" => FileType::MarkdownDocument,
81+
"terminal" => FileType::TerminalSettings,
82+
"zip" | "rar" | "7z" | "tar" | "gz" | "bz2" => FileType::ZipArchive,
83+
"dmg" => FileType::Dmg,
84+
"html" | "htm" => FileType::Html,
85+
"json" => FileType::Json,
86+
"xml" => FileType::Xml,
87+
"yaml" | "yml" => FileType::Yaml,
88+
"css" => FileType::Css,
89+
"vue" => FileType::Vue,
90+
"jsx" | "tsx" => FileType::React,
91+
"sql" => FileType::Sql,
92+
"csv" => FileType::Csv,
93+
"js" | "mjs" => FileType::Javascript,
94+
"ts" => FileType::Typescript,
95+
"py" | "pyw" => FileType::Python,
96+
"java" => FileType::Java,
97+
"go" => FileType::Golang,
98+
"rb" => FileType::Ruby,
99+
"php" => FileType::Php,
100+
"sass" | "scss" => FileType::Sass,
101+
"sketch" => FileType::Sketch,
102+
"ai" => FileType::AdobeAi,
103+
"psd" => FileType::AdobePsd,
104+
"prproj" => FileType::AdobePr,
105+
"aup" | "aup3" => FileType::AdobeAu,
106+
"aep" => FileType::AdobeAe,
107+
"lrcat" => FileType::AdobeLr,
108+
"xd" => FileType::AdobeXd,
109+
"fla" => FileType::AdobeFl,
110+
"indd" => FileType::AdobeId,
111+
"svg" => FileType::Svg,
112+
"epub" => FileType::Epub,
113+
_ => FileType::Unknown,
114+
}
115+
}
116+
117+
118+
fn type_to_icon(ty: FileType) -> &'static str {
119+
match ty {
120+
FileType::Folder => "font_file_folder",
121+
FileType::JPEGImage => "font_file_image",
122+
FileType::PNGImage => "font_file_image",
123+
FileType::PDFDocument => "font_file_document_pdf",
124+
FileType::PlainTextDocument => "font_file_txt",
125+
FileType::MicrosoftWordDocument => "font_file_document_word",
126+
FileType::MicrosoftExcelSpreadsheet => "font_file_spreadsheet_excel",
127+
FileType::AudioFile => "font_file_audio",
128+
FileType::VideoFile => "font_file_video",
129+
FileType::CHeaderFile => "font_file_csource",
130+
FileType::TOMLDocument => "font_file_toml",
131+
FileType::RustScript => "font_file_rustscript1",
132+
FileType::CSourceCode => "font_file_csource",
133+
FileType::MarkdownDocument => "font_file_markdown",
134+
FileType::TerminalSettings => "font_file_terminal1",
135+
FileType::ZipArchive => "font_file_zip",
136+
FileType::Dmg => "font_file_dmg",
137+
FileType::Html => "font_file_html",
138+
FileType::Json => "font_file_json",
139+
FileType::Xml => "font_file_xml",
140+
FileType::Yaml => "font_file_yaml",
141+
FileType::Css => "font_file_css",
142+
FileType::Vue => "font_file_vue",
143+
FileType::React => "font_file_react",
144+
FileType::Sql => "font_file_sql",
145+
FileType::Csv => "font_file_csv",
146+
FileType::Javascript => "font_file_javascript",
147+
FileType::Typescript => "font_file_typescript",
148+
FileType::Python => "font_file_python",
149+
FileType::Java => "font_file_java",
150+
FileType::Golang => "font_file_golang",
151+
FileType::Ruby => "font_file_ruby",
152+
FileType::Php => "font_file_php",
153+
FileType::Sass => "font_file_sass",
154+
FileType::Sketch => "font_file_sketch",
155+
FileType::AdobeAi => "font_file_adobe_ai",
156+
FileType::AdobePsd => "font_file_adobe_psd",
157+
FileType::AdobePr => "font_file_adobe_pr",
158+
FileType::AdobeAu => "font_file_adobe_au",
159+
FileType::AdobeAe => "font_file_adobe_ae",
160+
FileType::AdobeLr => "font_file_adobe_lr",
161+
FileType::AdobeXd => "font_file_adobe_xd",
162+
FileType::AdobeFl => "font_file_adobe_fl",
163+
FileType::AdobeId => "font_file_adobe_id",
164+
FileType::Svg => "font_file_svg",
165+
FileType::Epub => "font_file_epub",
166+
FileType::Unknown => "font_file_unknown",
167+
}
168+
}
169+
170+
171+
#[tauri::command]
172+
pub(crate) async fn get_file_icon(path: String) -> &'static str {
173+
let ty = get_file_type(path.as_str()).await;
174+
type_to_icon(ty)
175+
}

src-tauri/src/util/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
pub(crate) mod file;
2+
13
use std::{path::Path, process::Command};
24
use tauri::{AppHandle, Runtime};
35
use tauri_plugin_shell::ShellExt;

0 commit comments

Comments
 (0)