Fix serde field-naming bug that blanked show/episode names, real renames, and Undo

`#[serde(tag = "status", rename_all = "camelCase")]` on a tagged enum only
renames the tag's own values ("Found" -> "found"), not the field names
inside each struct-like variant - so `series_name` stayed `series_name` on
the wire instead of becoming `seriesName`. The frontend only ever reads
camelCase, so these fields came back `undefined`, and JSON.stringify
silently drops undefined keys when Tauri invoke args are serialized -
making the bug invisible rather than throwing.

This is why Fetch Data (TMDB/TVmaze/OMDb) blanked out {show name} and
{episode name} in naming schemes even on a full "found" result: reported
by the user with screenshots showing the naming preview correct after
Match but blank after Fetch Data.

The same pattern existed in 4 more places, fixed identically by adding
`rename_all_fields = "camelCase"` alongside the existing tag/rename_all:
- metadata.rs: FetchOutcome (the reported bug) and MovieFetchOutcome
- episodes.rs: EpisodeListOutcome
- history/mod.rs: RevertOutcome (restoredPath) - broke Undo reconciliation
- rename/mod.rs: RenameOutcome (newPath) - broke post-rename item tracking
  after a REAL on-disk rename; RenamePanel.tsx calls
  fileNameFromPath(result.outcome.newPath), which throws on undefined,
  so this was likely the most severe of the five.

No frontend changes needed - the TypeScript side already expected
camelCase throughout. Added 5 permanent regression tests (one per fixed
enum, two in metadata.rs) that assert the exact camelCase JSON keys and
assert the old snake_case keys are absent. cargo test --workspace: 186 ->
191 passing. npm run build: clean, no frontend diff.
This commit is contained in:
Renamr Scaffold
2026-08-30 04:12:17 +00:00
parent e219e8f2a8
commit ecd98d6c57
4 changed files with 101 additions and 5 deletions
+17 -1
View File
@@ -21,7 +21,7 @@ pub struct EpisodeRow {
}
#[derive(Debug, Clone, Serialize)]
#[serde(tag = "status", rename_all = "camelCase")]
#[serde(tag = "status", rename_all = "camelCase", rename_all_fields = "camelCase")]
pub enum EpisodeListOutcome {
Found {
series_name: String,
@@ -90,4 +90,20 @@ mod tests {
assert_eq!(row.title, "Ozymandias");
assert_eq!(row.air_date.as_deref(), Some("2013-09-15"));
}
// `#[serde(tag = "status", rename_all = "camelCase")]` alone only renames the tag's
// own values, not the field names inside a struct-like variant - see
// `metadata.rs`'s `serde_wire_format` tests for the full story and the bug this
// caught. `rename_all_fields = "camelCase"` on this enum is what actually renames
// `series_name` to `seriesName` on the wire; this test pins that.
#[test]
fn episode_list_outcome_found_serializes_with_camel_case_field_names() {
let outcome = EpisodeListOutcome::Found {
series_name: "Breaking Bad".to_string(),
episodes: vec![],
};
let json = serde_json::to_string(&outcome).unwrap();
assert!(json.contains("\"seriesName\":\"Breaking Bad\""), "got: {json}");
assert!(!json.contains("series_name"));
}
}