single instance & bug fixes

master
cast1e 2024-10-17 22:13:22 +08:00
parent c7ad45ebbb
commit c71ed9a982
15 changed files with 145 additions and 186 deletions

View File

@ -1,22 +0,0 @@
#include "pch.h"
#include "conFig.h"
conFig::conFig(const char* ffpath,const char* videoPath, BOOL mute) {
std::string tmp =ffpath;
this->ffpath = std::wstring(tmp.begin(), tmp.end());
tmp = videoPath;
this->videoPath = std::wstring(tmp.begin(), tmp.end());
this->mute = mute;
}
conFig::conFig(const conFig& config) {
this->ffpath = config.ffpath;
this->mute = config.mute;
this->videoPath = config.videoPath;
}
conFig::conFig() {
this->ffpath = L"";
this->mute = TRUE;
this->videoPath = L"";
}

View File

@ -1,13 +0,0 @@
#pragma once
#include <string>
class conFig
{
public:
std::wstring ffpath;
std::wstring videoPath;
BOOL mute;
conFig(const char* ffpath, const char* videoPath,BOOL mute);
conFig(const conFig& config);
conFig();
};

View File

@ -18,18 +18,6 @@ BOOL APIENTRY DllMain( HMODULE hModule,
return TRUE; return TRUE;
} }
playerInstance* player_instance = NULL;
extern "C" __declspec(dllexport) void init(const char* ffpath,const char* videoPath, BOOL mute) {
player_instance = new playerInstance(conFig(ffpath, videoPath, mute));
player_instance->generate();
}
extern "C" __declspec(dllexport) void destroy() {
player_instance->exit();
delete player_instance;
}
extern "C" __declspec(dllexport) BOOL set_wallpaper(const char* window_title) { extern "C" __declspec(dllexport) BOOL set_wallpaper(const char* window_title) {
return set_as_wallpaper(window_title); return set_as_wallpaper(window_title);
} }

View File

@ -1,11 +1,6 @@
#include "pch.h" #include "pch.h"
#include "playerInstance.h" #include "playerInstance.h"
playerInstance::playerInstance(const conFig& config) {
this->config = config;
this->hFfplay = NULL;
}
HWND hWorkerw = NULL; HWND hWorkerw = NULL;
static BOOL CALLBACK EnumWindowsProc(_In_ HWND hwnd, _In_ LPARAM Lparam) { static BOOL CALLBACK EnumWindowsProc(_In_ HWND hwnd, _In_ LPARAM Lparam) {
@ -17,67 +12,6 @@ static BOOL CALLBACK EnumWindowsProc(_In_ HWND hwnd, _In_ LPARAM Lparam) {
return TRUE; return TRUE;
} }
BOOL playerInstance::showWindow(LPCWSTR lpParameter) {
if (this->hFfplay != NULL) {
DWORD dwPID = 0;
GetWindowThreadProcessId(hFfplay, &dwPID);
char strCmd[MAX_PATH] = { 0 };
sprintf_s(strCmd, "taskkill /pid %d -f", dwPID);
system(strCmd);
}
STARTUPINFO si{ 0 };
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi{ 0 };
if (CreateProcess(this->config.ffpath.c_str(), (LPWSTR)lpParameter, 0, 0, 0, CREATE_NO_WINDOW, 0, 0, &si, &pi)) {
Sleep(600);//等待视频播放器启动完成
HWND hProgman = FindWindow(L"Progman", 0);// 找到PI窗口
SendMessageTimeout(hProgman, 0x052c, 0, 0, 0, 100, 0);// 给它发特殊消息
this->hFfplay = FindWindowW(L"SDL_app", 0);// 找到视频窗口
SetParent(hFfplay, hProgman);// 将视频窗口设苦为PM的子窗口
int systemWidth = GetSystemMetrics(0);
int systemHeight = GetSystemMetrics(1);
RECT cRct;
GetWindowRect(hFfplay, &cRct);
//if (horw) {
int width = cRct.right - cRct.left;
int x = (systemWidth - width) / 2;
MoveWindow(hFfplay, 0, 0, systemWidth, systemHeight, 1);
/* }
else {
int height = cRct.bottom - cRct.top;
int x = (sheight - height) / 2;
MoveWindow(hFfplay, 0, x, cRct.right - cRct.left, cRct.bottom - cRct.top, 0);
}*/
EnumWindows(EnumWindowsProc, 0);// 找到第二个workerw窗口并隐藏它
return TRUE;
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return FALSE;
}
void playerInstance::generate() {
std::wstring fcmd = L" \"";
fcmd += this->config.videoPath + L"\"";
fcmd += L" -noborder -loop 0";
if (this->config.mute) {
fcmd += L" -an";
}
fcmd += L" -fs";
this->showWindow(fcmd.c_str());
}
void playerInstance::exit() {
if (this->hFfplay != NULL) {
DWORD dwPID = 0;
GetWindowThreadProcessId(this->hFfplay, &dwPID);
char strCmd[MAX_PATH] = { 0 };
sprintf_s(strCmd, "taskkill /pid %d -f", dwPID);
system(strCmd);
}
}
BOOL try_find_worker(HWND hProgman,HWND hPlayer) { BOOL try_find_worker(HWND hProgman,HWND hPlayer) {
HWND hWorkerW = FindWindowEx(hProgman, 0, L"WorkerW", 0); HWND hWorkerW = FindWindowEx(hProgman, 0, L"WorkerW", 0);
if (hWorkerW != NULL) { if (hWorkerW != NULL) {
@ -87,10 +21,9 @@ BOOL try_find_worker(HWND hProgman,HWND hPlayer) {
else return FALSE; else return FALSE;
} }
BOOL shell_in_progman(HWND hProgman) { HWND shell_in_progman(HWND hProgman) {
HWND hShell = FindWindowEx(hProgman, 0, L"SHELLDLL_DefView", 0); HWND hShell = FindWindowEx(hProgman, 0, L"SHELLDLL_DefView", 0);
if (hShell) return TRUE; return hShell;
else return FALSE;
} }
BOOL set_as_wallpaper(const char* window_title) { BOOL set_as_wallpaper(const char* window_title) {
@ -99,8 +32,15 @@ BOOL set_as_wallpaper(const char* window_title) {
std::string tmp = window_title; std::string tmp = window_title;
HWND hPlayer = FindWindowW(0, std::wstring(tmp.begin(), tmp.end()).c_str());// 找到视频窗口 HWND hPlayer = FindWindowW(0, std::wstring(tmp.begin(), tmp.end()).c_str());// 找到视频窗口
if (hPlayer == NULL) return FALSE; if (hPlayer == NULL) return FALSE;
if (shell_in_progman(hProgman)) { HWND hDefView = shell_in_progman(hProgman);
return try_find_worker(hProgman, hPlayer); if (hDefView!=NULL) {
if (try_find_worker(hProgman, hPlayer)) {
ShowWindow(hDefView, SW_HIDE);
Sleep(0);
ShowWindow(hDefView, SW_SHOWNORMAL);
return TRUE;
}
else return FALSE;
} }
else { else {
SetParent(hPlayer, hProgman);// 将视频窗口设苦为PM的子窗口 SetParent(hPlayer, hProgman);// 将视频窗口设苦为PM的子窗口

View File

@ -1,17 +1,5 @@
#pragma once #pragma once
#include <string> #include <string>
#include "conFig.h"
class playerInstance
{
private:
HWND hFfplay;
conFig config;
public:
playerInstance(const conFig& config);
BOOL showWindow(LPCWSTR lpParameter);
void generate();
void exit();
};
BOOL set_as_wallpaper(const char* window_title); BOOL set_as_wallpaper(const char* window_title);
BOOL detectWindowMaximized(); BOOL detectWindowMaximized();

View File

@ -142,13 +142,11 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="conFig.h" />
<ClInclude Include="framework.h" /> <ClInclude Include="framework.h" />
<ClInclude Include="pch.h" /> <ClInclude Include="pch.h" />
<ClInclude Include="playerInstance.h" /> <ClInclude Include="playerInstance.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="conFig.cpp" />
<ClCompile Include="dllmain.cpp" /> <ClCompile Include="dllmain.cpp" />
<ClCompile Include="pch.cpp"> <ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>

View File

@ -24,9 +24,6 @@
<ClInclude Include="playerInstance.h"> <ClInclude Include="playerInstance.h">
<Filter>头文件</Filter> <Filter>头文件</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="conFig.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="dllmain.cpp"> <ClCompile Include="dllmain.cpp">
@ -38,8 +35,5 @@
<ClCompile Include="playerInstance.cpp"> <ClCompile Include="playerInstance.cpp">
<Filter>源文件</Filter> <Filter>源文件</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="conFig.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -103,6 +103,30 @@ dependencies = [
"pin-project-lite", "pin-project-lite",
] ]
[[package]]
name = "async-executor"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec"
dependencies = [
"async-task",
"concurrent-queue",
"fastrand",
"futures-lite",
"slab",
]
[[package]]
name = "async-fs"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a"
dependencies = [
"async-lock",
"blocking",
"futures-lite",
]
[[package]] [[package]]
name = "async-io" name = "async-io"
version = "2.3.4" version = "2.3.4"
@ -3685,6 +3709,21 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "tauri-plugin-single-instance"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a25ac834491d089699a2bc9266a662faf373c9f779f05a2235bc6e4d9e61769a"
dependencies = [
"log",
"serde",
"serde_json",
"tauri",
"thiserror",
"windows-sys 0.59.0",
"zbus",
]
[[package]] [[package]]
name = "tauri-runtime" name = "tauri-runtime"
version = "2.1.0" version = "2.1.0"
@ -4213,6 +4252,7 @@ dependencies = [
"tauri-plugin-dialog", "tauri-plugin-dialog",
"tauri-plugin-fs", "tauri-plugin-fs",
"tauri-plugin-shell", "tauri-plugin-shell",
"tauri-plugin-single-instance",
"window-vibrancy", "window-vibrancy",
] ]
@ -4866,9 +4906,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b8e3d6ae3342792a6cc2340e4394334c7402f3d793b390d2c5494a4032b3030" checksum = "7b8e3d6ae3342792a6cc2340e4394334c7402f3d793b390d2c5494a4032b3030"
dependencies = [ dependencies = [
"async-broadcast", "async-broadcast",
"async-executor",
"async-fs",
"async-io",
"async-lock",
"async-process", "async-process",
"async-recursion", "async-recursion",
"async-task",
"async-trait", "async-trait",
"blocking",
"derivative", "derivative",
"enumflags2", "enumflags2",
"event-listener", "event-listener",

View File

@ -29,4 +29,6 @@ lazy_static = "1.5.0"
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
tauri-plugin-autostart = "2.0.0-rc" tauri-plugin-autostart = "2.0.0-rc"
tauri-plugin-single-instance = "2.0.0-rc"

View File

@ -1,20 +1,32 @@
use libloading::{self,Library}; use crate::handler::get_absolute_path;
use std::{ffi::CString, ops::Deref, sync::Arc};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use libloading::{self, Library};
use std::{ffi::CString, ops::Deref, sync::Arc};
struct CoreModule{ struct CoreModule {
_module:Arc<Library>, _module: Arc<Library>,
pub set_wallpaper:libloading::os::windows::Symbol<unsafe extern "C" fn(*const i8) -> i8>, pub set_wallpaper: libloading::os::windows::Symbol<unsafe extern "C" fn(*const i8) -> i8>,
pub any_maximized:libloading::os::windows::Symbol<unsafe extern "C" fn() -> i8> pub any_maximized: libloading::os::windows::Symbol<unsafe extern "C" fn() -> i8>,
} }
impl CoreModule { impl CoreModule {
fn new(library_path: &str) -> CoreModule { fn new(library_path: &str) -> CoreModule {
let library_dir = get_absolute_path(&String::from(library_path));
// 首先加载动态库 // 首先加载动态库
let _module = Arc::new(unsafe { Library::new(library_path).unwrap()}); let _module = Arc::new(unsafe { Library::new(library_dir).unwrap() });
// 然后获取符号 // 然后获取符号
let set_wallpaper: libloading::os::windows::Symbol<unsafe extern "C" fn(*const i8) -> i8> = unsafe { _module.get::<unsafe extern "C" fn(*const i8) -> i8>(b"set_wallpaper\0").unwrap().into_raw() }; let set_wallpaper: libloading::os::windows::Symbol<unsafe extern "C" fn(*const i8) -> i8> = unsafe {
let any_maximized: libloading::os::windows::Symbol<unsafe extern "C" fn() -> i8> = unsafe { _module.get::<unsafe extern "C" fn() -> i8>(b"any_maximized\0").unwrap().into_raw() }; _module
.get::<unsafe extern "C" fn(*const i8) -> i8>(b"set_wallpaper\0")
.unwrap()
.into_raw()
};
let any_maximized: libloading::os::windows::Symbol<unsafe extern "C" fn() -> i8> = unsafe {
_module
.get::<unsafe extern "C" fn() -> i8>(b"any_maximized\0")
.unwrap()
.into_raw()
};
// 返回初始化的结构体 // 返回初始化的结构体
CoreModule { CoreModule {
_module, _module,
@ -24,8 +36,8 @@ impl CoreModule {
} }
} }
lazy_static!{ lazy_static! {
static ref core_module:CoreModule = CoreModule::new("wallitor-core.dll"); static ref core_module: CoreModule = CoreModule::new("wallitor-core.dll");
} }
#[tauri::command] #[tauri::command]
@ -41,10 +53,10 @@ pub async fn set_wallpaper(title: String) -> bool {
} }
#[tauri::command] #[tauri::command]
pub async fn any_zoomed()->bool{ pub async fn any_zoomed() -> bool {
unsafe { unsafe {
let res = core_module.any_maximized.deref()(); let res = core_module.any_maximized.deref()();
if res == 0{ if res == 0 {
return false; return false;
} }
} }

View File

@ -1,3 +1,4 @@
use crate::handler::get_absolute_path;
use crate::{reader, VERSION}; use crate::{reader, VERSION};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::json; use serde_json::json;
@ -7,9 +8,9 @@ use tauri::ipc::Response;
#[tauri::command] #[tauri::command]
pub async fn get_file(path: String) -> Response { pub async fn get_file(path: String) -> Response {
let p = Path::new(&path); let p = get_absolute_path(&path);
if let Ok(true) = fs::exists(p) { if let Ok(true) = fs::exists(&p) {
let data: Vec<u8> = fs::read(p).unwrap(); let data: Vec<u8> = fs::read(&p).unwrap();
return tauri::ipc::Response::new(data); return tauri::ipc::Response::new(data);
} }
tauri::ipc::Response::new(String::from("")) tauri::ipc::Response::new(String::from(""))
@ -18,12 +19,12 @@ pub async fn get_file(path: String) -> Response {
#[tauri::command] #[tauri::command]
pub async fn read_resource_dir() -> String { pub async fn read_resource_dir() -> String {
let mut file_map = reader::FileMap::new(); let mut file_map = reader::FileMap::new();
let path = Path::new(".\\resource"); let path = get_absolute_path(&String::from(".\\resource"));
if let Ok(false) = fs::exists(path) { if let Ok(false) = fs::exists(&path) {
fs::create_dir(path).expect("Can't create dir"); fs::create_dir(&path).expect("Can't create dir");
} }
file_map file_map
.read_resourse_directory(path) .read_resourse_directory(&path)
.expect("Can't read dir"); .expect("Can't read dir");
serde_json::to_string(&file_map).unwrap() serde_json::to_string(&file_map).unwrap()
} }
@ -32,9 +33,10 @@ pub async fn read_resource_dir() -> String {
pub async fn del_folder(path: String) -> bool { pub async fn del_folder(path: String) -> bool {
let p = Path::new(&path); let p = Path::new(&path);
if p.starts_with(".\\") { if p.starts_with(".\\") {
if p.is_dir() { let folder_path = get_absolute_path(&path);
if let Ok(true) = fs::exists(p) { if folder_path.is_dir() {
if fs::remove_dir_all(p).is_ok() { if let Ok(true) = fs::exists(&folder_path) {
if fs::remove_dir_all(&folder_path).is_ok() {
return true; return true;
} }
} }
@ -66,7 +68,7 @@ static SETTING_PATH: &str = "./settings.json";
#[tauri::command] #[tauri::command]
pub async fn get_settings() -> String { pub async fn get_settings() -> String {
let setting_path = Path::new(SETTING_PATH); let setting_path = get_absolute_path(&String::from(SETTING_PATH));
if let Ok(file) = fs::read(setting_path) { if let Ok(file) = fs::read(setting_path) {
let mut settings: Settings = serde_json::from_slice(&file).unwrap(); let mut settings: Settings = serde_json::from_slice(&file).unwrap();
settings.version = String::from(VERSION); settings.version = String::from(VERSION);
@ -79,7 +81,7 @@ pub async fn get_settings() -> String {
#[tauri::command] #[tauri::command]
pub async fn set_settings(settings: Settings) -> bool { pub async fn set_settings(settings: Settings) -> bool {
let setting_path = Path::new(SETTING_PATH); let setting_path = get_absolute_path(&String::from(SETTING_PATH));
if fs::write(setting_path, json!(settings).to_string()).is_ok() { if fs::write(setting_path, json!(settings).to_string()).is_ok() {
return true; return true;
} }

View File

@ -1,3 +1,11 @@
pub mod apply;
pub mod file; pub mod file;
pub mod wallpaper; pub mod wallpaper;
pub mod apply;
use std::path::{Path, PathBuf};
pub fn get_absolute_path(path: &String) -> PathBuf {
let binding = std::env::current_exe().unwrap();
let base_dir = binding.parent().unwrap();
return base_dir.join(Path::new(path));
}

View File

@ -1,3 +1,4 @@
use crate::handler::get_absolute_path;
use chrono::Local; use chrono::Local;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::{self, json}; use serde_json::{self, json};
@ -34,7 +35,8 @@ pub struct Config {
#[tauri::command] #[tauri::command]
pub async fn new_wallpaper(info: AddInfo) -> String { pub async fn new_wallpaper(info: AddInfo) -> String {
let base_url = String::from("./resource"); let base_path = get_absolute_path(&String::from("./resource"));
let base_url = base_path.to_str().unwrap();
let current_time: i64 = Local::now().timestamp(); let current_time: i64 = Local::now().timestamp();
let folder = format!("{}/{}", base_url, current_time); let folder = format!("{}/{}", base_url, current_time);
if fs::create_dir_all(Path::new(&folder)).is_err() { if fs::create_dir_all(Path::new(&folder)).is_err() {
@ -143,10 +145,10 @@ fn copy_preview(source_file: &String, target_dir: &String) -> bool {
#[tauri::command] #[tauri::command]
pub async fn edit_wallpaper(info: EditInfo) -> bool { pub async fn edit_wallpaper(info: EditInfo) -> bool {
let folder_path = Path::new(&info.path); let folder_path = &get_absolute_path(&info.path);
if let Ok(true) = fs::exists(folder_path) { if let Ok(true) = fs::exists(folder_path) {
let config_path_str = format!("{}/config.json", info.path); let config_path_str = format!("{}/config.json", info.path);
let config_path = Path::new(&config_path_str); let config_path = &get_absolute_path(&config_path_str);
if let Ok(file) = fs::read(config_path) { if let Ok(file) = fs::read(config_path) {
let mut config: Config = serde_json::from_slice(&file).unwrap(); let mut config: Config = serde_json::from_slice(&file).unwrap();
config.info.description = info.description; config.info.description = info.description;

View File

@ -2,6 +2,7 @@ mod handler;
mod reader; mod reader;
mod setup; mod setup;
extern crate lazy_static; extern crate lazy_static;
use tauri::Manager;
use tauri_plugin_autostart::MacosLauncher; use tauri_plugin_autostart::MacosLauncher;
static VERSION: &str = "1.0.0"; static VERSION: &str = "1.0.0";
@ -10,11 +11,18 @@ static VERSION: &str = "1.0.0";
pub fn run() { pub fn run() {
tauri::Builder::default() tauri::Builder::default()
.setup(setup::init) .setup(setup::init)
.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
let window = app.get_webview_window("main").expect("no main window");
if let Ok(true) = window.is_minimized() {
let _ = window.unminimize();
}
let _ = window.set_focus();
}))
.plugin(tauri_plugin_fs::init()) .plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_autostart::init( .plugin(tauri_plugin_autostart::init(
MacosLauncher::LaunchAgent, MacosLauncher::LaunchAgent,
Some(vec!["--flag1", "--flag2"]), None,
)) ))
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
handler::file::get_file, handler::file::get_file,

View File

@ -1,11 +1,11 @@
use serde::{Serialize, Serializer};
use std::collections::HashMap;
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
use serde::{ Serialize,Serializer};
use std::collections::HashMap;
enum FileType { enum FileType {
File(String), File(String),
Directory(HashMap<String,FileType>) Directory(HashMap<String, FileType>),
} }
impl Serialize for FileType { impl Serialize for FileType {
@ -26,31 +26,37 @@ pub struct FileMap {
} }
impl FileMap { impl FileMap {
pub fn new()->FileMap{ pub fn new() -> FileMap {
FileMap{ FileMap {
files:HashMap::new() files: HashMap::new(),
} }
} }
fn read_resource(&self,p:&Path)->std::io::Result<HashMap<String,FileType>>{ fn read_resource(&self, p: &Path) -> std::io::Result<HashMap<String, FileType>> {
let mut files:HashMap<String,FileType> = HashMap::new(); let mut files: HashMap<String, FileType> = HashMap::new();
for entry in fs::read_dir(p)?{ for entry in fs::read_dir(p)? {
let dir = entry?; let dir = entry?;
let path = dir.path(); let path = dir.path();
if path.is_file() { if path.is_file() {
files.insert(path.file_name().unwrap().to_string_lossy().to_string(), FileType::File(path.to_string_lossy().to_string())); files.insert(
path.file_name().unwrap().to_string_lossy().to_string(),
FileType::File(path.to_string_lossy().to_string()),
);
} }
} }
Ok(files) Ok(files)
} }
pub fn read_resourse_directory(&mut self,p:&Path)->std::io::Result<()>{ pub fn read_resourse_directory(&mut self, p: &Path) -> std::io::Result<()> {
for entry in fs::read_dir(p)?{ for entry in fs::read_dir(p)? {
let dir = entry?; let dir = entry?;
let path = dir.path(); let path = dir.path();
if path.is_dir() { if path.is_dir() {
let resource = self.read_resource(path.as_path())?; let resource = self.read_resource(path.as_path())?;
self.files.insert(path.to_string_lossy().to_string(), FileType::Directory(resource)) ; self.files.insert(
path.to_string_lossy().to_string(),
FileType::Directory(resource),
);
} }
} }
Ok(()) Ok(())