mirror of
https://github.com/storytold/wordcraft.git
synced 2026-11-09 20:00:11 -06:00
Preserve AbortError cancellation and report download fallback failures without marking saves successful. Fixes #1246 Assisted-by: OpenAI Codex Co-authored-by: Codex <codex@openai.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>
47 lines
1.5 KiB
Rust
47 lines
1.5 KiB
Rust
//! Save-picker rejection policy, shared with native tests of the browser fallback.
|
|
|
|
use wordcraft_ui_egui::async_saves::SaveOutcome;
|
|
|
|
/// A cancelled picker ends the save. Other picker failures try the browser download path.
|
|
/// Write/close errors do not pass through this function: they retain their own failure.
|
|
pub(crate) fn picker_rejected(name: &str, download: impl FnOnce() -> Result<(), String>) -> SaveOutcome {
|
|
if name == "AbortError" {
|
|
SaveOutcome::Cancelled
|
|
} else {
|
|
match download() {
|
|
Ok(()) => SaveOutcome::Saved,
|
|
Err(error) => SaveOutcome::Failed(error),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn unavailable_picker_downloads_once() {
|
|
for name in ["SecurityError", "NotSupportedError", "TypeError", ""] {
|
|
let mut calls = 0;
|
|
let outcome = picker_rejected(name, || {
|
|
calls += 1;
|
|
Ok(())
|
|
});
|
|
assert_eq!(outcome, SaveOutcome::Saved);
|
|
assert_eq!(calls, 1);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn cancelled_picker_never_downloads() {
|
|
let outcome = picker_rejected("AbortError", || panic!("cancel must not download"));
|
|
assert_eq!(outcome, SaveOutcome::Cancelled);
|
|
}
|
|
|
|
#[test]
|
|
fn failed_fallback_remains_a_failed_save() {
|
|
let outcome = picker_rejected("SecurityError", || Err("download unavailable".into()));
|
|
assert_eq!(outcome, SaveOutcome::Failed("download unavailable".into()));
|
|
}
|
|
}
|