2025-11-18 14:46:51 +08:00
|
|
|
import { singleton } from 'tsyringe';
|
2025-11-25 22:23:19 +08:00
|
|
|
import { invoke, convertFileSrc } from '@tauri-apps/api/core';
|
2025-11-18 14:46:51 +08:00
|
|
|
import type { IFileSystem, FileEntry } from '@esengine/editor-core';
|
|
|
|
|
|
|
|
|
|
@singleton()
|
|
|
|
|
export class TauriFileSystemService implements IFileSystem {
|
2025-11-25 22:23:19 +08:00
|
|
|
dispose(): void {
|
|
|
|
|
// No cleanup needed
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-18 14:46:51 +08:00
|
|
|
async readFile(path: string): Promise<string> {
|
|
|
|
|
return await invoke<string>('read_file_content', { path });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async writeFile(path: string, content: string): Promise<void> {
|
|
|
|
|
await invoke('write_file_content', { path, content });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async writeBinary(path: string, data: Uint8Array): Promise<void> {
|
|
|
|
|
await invoke('write_binary_file', { filePath: path, content: Array.from(data) });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async exists(path: string): Promise<boolean> {
|
|
|
|
|
try {
|
2025-12-04 14:04:39 +08:00
|
|
|
// 首先尝试作为目录列出内容
|
|
|
|
|
// First try to list as directory
|
|
|
|
|
await invoke('list_directory', { path });
|
2025-11-18 14:46:51 +08:00
|
|
|
return true;
|
|
|
|
|
} catch {
|
2025-12-04 14:04:39 +08:00
|
|
|
// 如果不是目录,尝试读取文件
|
|
|
|
|
// If not a directory, try reading as file
|
|
|
|
|
try {
|
|
|
|
|
await invoke('read_file_content', { path });
|
|
|
|
|
return true;
|
|
|
|
|
} catch {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-11-18 14:46:51 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async createDirectory(path: string): Promise<void> {
|
|
|
|
|
await invoke('create_directory', { path });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async listDirectory(path: string): Promise<FileEntry[]> {
|
2025-12-04 14:04:39 +08:00
|
|
|
const entries = await invoke<Array<{
|
|
|
|
|
name: string;
|
|
|
|
|
path: string;
|
|
|
|
|
is_dir: boolean;
|
|
|
|
|
size?: number;
|
|
|
|
|
modified?: number;
|
|
|
|
|
}>>('list_directory', { path });
|
2025-11-23 14:49:37 +08:00
|
|
|
return entries.map((entry) => ({
|
2025-11-18 14:46:51 +08:00
|
|
|
name: entry.name,
|
2025-11-23 14:49:37 +08:00
|
|
|
isDirectory: entry.is_dir,
|
2025-12-04 14:04:39 +08:00
|
|
|
path: entry.path,
|
|
|
|
|
size: entry.size,
|
|
|
|
|
modified: entry.modified ? new Date(entry.modified * 1000) : undefined
|
2025-11-18 14:46:51 +08:00
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async deleteFile(path: string): Promise<void> {
|
|
|
|
|
await invoke('delete_file', { path });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async deleteDirectory(path: string): Promise<void> {
|
|
|
|
|
await invoke('delete_directory', { path });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async scanFiles(basePath: string, pattern: string): Promise<string[]> {
|
2025-12-03 22:15:22 +08:00
|
|
|
return await invoke<string[]>('scan_directory', { path: basePath, pattern });
|
2025-11-18 14:46:51 +08:00
|
|
|
}
|
2025-11-25 22:23:19 +08:00
|
|
|
|
|
|
|
|
convertToAssetUrl(filePath: string): string {
|
|
|
|
|
return convertFileSrc(filePath);
|
|
|
|
|
}
|
2025-11-18 14:46:51 +08:00
|
|
|
}
|