Skip to content

Commit 77bf5be

Browse files
committed
feat: timestamp exported backup filenames
1 parent 1c63f6e commit 77bf5be

3 files changed

Lines changed: 33 additions & 3 deletions

File tree

e2e/data-transfer.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ test.describe('data transfer', () => {
2525
const revealCall = calls.find((call) => call.cmd === 'show_item_in_folder')
2626
return revealCall ? firstInvokeArg(revealCall) : null
2727
})
28-
.toBe('/Users/e2e/exports/swh_data.json')
28+
.toBe('/Users/e2e/exports/switchhosts_20260509_121436.789.json')
2929
})
3030

3131
test('imports backup data from a file', async ({ page }) => {

e2e/support/tauri-mock.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@
407407
}
408408
return refreshRemote(params[0])
409409
case 'export_data':
410-
return '/Users/e2e/exports/swh_data.json'
410+
return '/Users/e2e/exports/switchhosts_20260509_121436.789.json'
411411
case 'import_data':
412412
if (state.nextImportDelayMs) {
413413
const ms = state.nextImportDelayMs

src-tauri/src/commands.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,14 @@ pub async fn show_item_in_folder(args: Args) -> Value {
10401040
// come back as Ok(Value::String("error_code")) the renderer can
10411041
// display.
10421042

1043+
fn export_file_name_for(now: chrono::DateTime<chrono::Local>) -> String {
1044+
format!("switchhosts_{}.json", now.format("%Y%m%d_%H%M%S%.3f"))
1045+
}
1046+
1047+
fn default_export_file_name() -> String {
1048+
export_file_name_for(chrono::Local::now())
1049+
}
1050+
10431051
#[tauri::command]
10441052
pub async fn export_data<R: Runtime>(
10451053
app: AppHandle<R>,
@@ -1050,7 +1058,7 @@ pub async fn export_data<R: Runtime>(
10501058
.dialog()
10511059
.file()
10521060
.add_filter("JSON", &["json"])
1053-
.set_file_name("swh_data.json")
1061+
.set_file_name(&default_export_file_name())
10541062
.blocking_save_file();
10551063

10561064
let Some(dest) = picked else {
@@ -1070,6 +1078,28 @@ pub async fn export_data<R: Runtime>(
10701078
Ok(Value::String(dest_path.display().to_string()))
10711079
}
10721080

1081+
#[cfg(test)]
1082+
mod export_file_name_tests {
1083+
use chrono::{TimeZone, Timelike};
1084+
1085+
use super::export_file_name_for;
1086+
1087+
#[test]
1088+
fn includes_millisecond_timestamp() {
1089+
let now = chrono::Local
1090+
.with_ymd_and_hms(2026, 5, 9, 12, 14, 36)
1091+
.single()
1092+
.expect("test timestamp should be representable")
1093+
.with_nanosecond(789_000_000)
1094+
.expect("test nanosecond should be valid");
1095+
1096+
assert_eq!(
1097+
export_file_name_for(now),
1098+
"switchhosts_20260509_121436.789.json"
1099+
);
1100+
}
1101+
}
1102+
10731103
#[tauri::command]
10741104
pub async fn import_data<R: Runtime>(
10751105
app: AppHandle<R>,

0 commit comments

Comments
 (0)