Skip to content

[WIP] Rewrite PS5 Vault as Rust/Tauri v2 application#37

Closed
NookieAI with Copilot wants to merge 1 commit into
mainfrom
copilot/migrate-ps5-vault-to-rust-tauri-v2
Closed

[WIP] Rewrite PS5 Vault as Rust/Tauri v2 application#37
NookieAI with Copilot wants to merge 1 commit into
mainfrom
copilot/migrate-ps5-vault-to-rust-tauri-v2

Conversation

Copilot AI commented Mar 11, 2026

Copy link
Copy Markdown
Contributor
  • Create src-tauri/Cargo.toml
  • Create src-tauri/build.rs
  • Create src-tauri/tauri.conf.json
  • Create src-tauri/src/main.rs
  • Create src-tauri/src/lib.rs
  • Create src-tauri/src/state.rs
  • Create src-tauri/src/models.rs
  • Create src-tauri/src/commands/mod.rs
  • Create src-tauri/src/commands/scan.rs
  • Create src-tauri/src/commands/transfer.rs
  • Create src-tauri/src/commands/ftp.rs
  • Create src-tauri/src/commands/local_ops.rs
  • Create src-tauri/src/commands/drives.rs
  • Create src-tauri/src/commands/verify.rs
  • Create src-tauri/src/commands/api_key.rs
  • Create src-tauri/src/api_server.rs
  • Create tauri-bridge.js
  • Update index.html (add tauri-bridge.js script tag)
  • Update package.json (remove Electron, add Tauri CLI)
  • Update .gitignore (add src-tauri/target/)
  • Run cargo check to validate Rust code compiles
Original prompt

Goal

Rewrite PS5 Vault (currently Electron + Node.js) as a Rust/Tauri v2 desktop application. Every single feature must work identically to the Electron version. Do not break or remove anything. Solve every problem you encounter and produce production-quality, compiling code.


Current Electron Architecture

Files to replace / migrate

File Size Role
main.js 186 KB Main process: scan, transfer, FTP, IPC handlers, all business logic
api-server.js 12.8 KB Local HTTP REST + SSE server on port 3731
preload.js 5.3 KB Electron contextBridge → exposes window.ppsaApi
ftp.js 10 KB FTP helpers (frontend-side)
renderer.js 157 KB UI logic
index.html 67 KB Main window HTML
package.json Electron 29 + electron-builder

window.ppsaApi surface (from preload.js) — ALL must be preserved

openDirectory, showInFolder, openExternal, copyToClipboard,
scanSource(src, opts), getAllDrives, cancelOperation,
ensureAndPopulate(opts), checkConflicts(items, dest, layout, customName),
moveToLayout(item, dest, layout), resumeTransfer(state),
deleteItem(item), trashItem(item), renameItem(item, name),
ps5Discover(timeout), ftpTestConnection(cfg), ftpStorageInfo(cfg, items),
ftpRenameItem(cfg, old, nw), ftpDeleteItem(cfg, path),
clearFtpSizeCache, ftpCacheStats,
verifyLibrary(items, ftpCfg), listGameSubfolders(p, cfg),
getChecksumDb, recordTransferChecksums(data),
getApiKey, getApiStatus, regenerateApiKey,
onProgress(cb), onScanProgress(cb), onApiEvent(cb), removeAllListeners

API Server (port 3731) endpoints — ALL must be preserved

GET  /api/v1/status
GET  /api/v1/library
GET  /api/v1/library/:ppsa
GET  /api/v1/library/:ppsa/icon
POST /api/v1/scan
GET  /api/v1/scan/status
POST /api/v1/transfer
GET  /api/v1/transfer/status
GET  /api/v1/events   (SSE)
Auth: X-API-Key header

Key constants from main.js

MAX_SCAN_DEPTH = 12
SCAN_CONCURRENCY = 64
DIR_READDIR_TIMEOUT_MS = 8000
LOCAL_READDIR_TIMEOUT_MS = 10000
MAX_FILE_SIZE_BYTES = 200GB
RETRY_ATTEMPTS = 3
RETRY_DELAY_MS = 100
DISK_SPACE_SAFETY_BUFFER_BYTES = 512MB
MAX_FILES_TO_CHECK_FOR_CORRUPTION = 500

What to build

1. src-tauri/Cargo.toml

Use Tauri v2. Include these crates:

  • tauri = { version = "2", features = ["protocol-asset"] }
  • tauri-build = "2" (build-dep)
  • tokio = { version = "1", features = ["full"] }
  • serde = { version = "1", features = ["derive"] }
  • serde_json = "1"
  • suppaftp = { version = "6", features = ["async-native-tls"] } — replaces basic-ftp
  • axum = "0.7" — for the REST/SSE API server
  • axum-extra = { version = "0.9", features = ["typed-header"] }
  • tower-http = { version = "0.5", features = ["cors"] }
  • tokio-stream = "0.1"
  • sha2 = "0.10"
  • hex = "0.4"
  • uuid = { version = "1", features = ["v4"] }
  • rand = "0.8"
  • chrono = { version = "0.4", features = ["serde"] }
  • anyhow = "1"
  • dirs = "5"
  • opener = "0.7" — for shell open / show in folder
  • arboard = "3" — clipboard
  • sysinfo = "0.30" — drive enumeration

2. src-tauri/tauri.conf.json

{
  "productName": "PS5 Vault",
  "version": "2.3.0",
  "identifier": "com.ps5vault.app",
  "build": {
    "frontendDist": "../"
  },
  "bundle": {
    "active": true,
    "targets": "all",
    "icon": ["assets/icon.ico", "assets/icon.icns", "assets/icon.png"]
  },
  "app": {
    "windows": [{
      "title": "PS5 Vault",
      "width": 1280,
      "height": 800,
      "resizable": true
    }],
    "security": { "csp": null }
  }
}

3. src-tauri/build.rs

Standard Tauri build script.

4. src-tauri/src/main.rs

Entry point: initialise shared AppState, start Axum API server as a tokio::spawn task on port 3731, register all Tauri commands, run the Tauri app.

5. src-tauri/src/state.rs

pub struct AppState {
    pub library: Arc<Mutex<Vec<GameItem>>>,
    pub scan_active: Arc<AtomicBool>,
    pub scan_source: Arc<Mutex<String>>,
    pub scan_progress: Arc<Mutex<ScanProgress>>,
    pub transfer_active: Arc<AtomicBool>,
    pub transfer_progress: Arc<Mutex<TransferProgress>>,
    pub cancel_flag: Arc<AtomicBool>,
    pub ftp_size_cache: Arc<Mutex<HashMap<String, FtpCacheEntry>>>,
    pub checksum_db: Arc<Mutex<HashMap<String, String>>>,
    pub api_key: Arc<Mutex<String>>,
    pub sse_tx: broadcast::Sender<String>,
}

6. src-tauri/src/models.rs

All shared structs with Serialize/Deserialize:

  • GameItem — title, titleId (PPSA…), contentFolderPath, folderPath, folderName, displayTitle, dbTitle, sizeBytes, iconPath, platform, contentType, etc. Mirror every field that renderer.js uses.
  • ScanProgress { found, sized, total }
  • TransferProgress { done, total, currentFile, bytesTransferred, totalBytes, speed }
  • FtpConfig { host, port, user, pass, passiveMode }
  • FtpCacheEntry { size_bytes, cached_at }
  • ScanOpts { deep, skipSized, includePs4 }
  • `ConflictCheckResul...

This pull request was created from Copilot chat.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants