Skip to content

fix(scripting): serialize empty snapshot fields as nil - #740

Merged
LargeModGames merged 7 commits into
LargeModGames:mainfrom
jum-apzn:fix/lua-snapshot-nil
Oct 11, 2026
Merged

LargeModGames merged 7 commits into
LargeModGames:mainfrom
jum-apzn:fix/lua-snapshot-nil

Conversation

@jum-apzn

@jum-apzn jum-apzn commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes #736.

Use one snapshot serializer for the seven synchronous API reads, event playback payloads, and nine asynchronous data reads. It changes only serialize_none_to_null to false, so absent optional fields are Lua nil and ordinary if field then guards behave as documented.

json_decode and storage_get keep their existing serialization and null sentinel. Add two regressions for synchronous reads and event payloads, plus an Unreleased changelog entry. No snapshot types, dependencies, scripting docs, or gate counters change.

Testing

Run on Linux x86_64 with Rust/cargo/clippy 1.99.0. The following outputs are from actual local runs:

# Before the fix, with only the two new regression tests added:
$ cargo test reach_lua_as_nil
left: "false:false:false", right: "true:true:true"
left: "false", right: "true"
test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 1913 filtered out

# With the fix:
$ cargo test reach_lua_as_nil
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 1913 filtered out

$ cargo test json_null_decodes_to_sentinel_not_nil
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1914 filtered out

$ cargo fmt --all -- --check
# No output; exit 0.

$ cargo clippy -- -D warnings
Finished `dev` profile [unoptimized] target(s) in 1m 05s
# Exit 0.

$ cargo test
test result: ok. 1915 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

$ cargo clippy --no-default-features --features telemetry,tui -- -D warnings
Finished `dev` profile [unoptimized] target(s) in 27.63s
# Exit 0.

$ cargo test --no-default-features --features telemetry,tui
test result: ok. 1506 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

The full default suite includes all eight existing plugin-storage tests. Both full suites also completed their binary and doc-test targets successfully (zero tests there).

Additional notes

  • Build settings: two Cargo jobs, debug information disabled for dev/test profiles. The cloud environment already had ALSA 1.2.14 but no alsa.pc, so a task-local pkg-config file and symlink to the installed library were used. No system packages were installed.
  • Test builds emit an existing session_plays dead-code warning, also present before the fix; the required clippy commands are clean.
  • Not validated: the remaining CI feature matrix, macOS, live Spotify/audio use, and GUI checks. npm ci in gui/ was attempted but failed with ENOENT creating the environment's default /home/agent/.npm cache; no GUI lint, format, typecheck, tests, or build ran.
  • AI disclosure: OpenAI-powered dot prepared the implementation, regression tests, and this description. The listed verification commands were run against the patch.

Summary by CodeRabbit

  • Bug Fixes
    • Missing values in Lua snapshots now appear as nil across playback, current-track, device, playlist, queue, search, configuration, and plugin data. This includes absent playback and track details, as well as device information provided to event handlers. JSON decoding and plugin storage continue to retain their existing null representation.

Use the reviewed snapshot serializer for event playback and asynchronous reads. AI-assisted implementation and regression verification by OpenAI-powered dot.

Signed-off-by: 점[dot] <jum.apzn@gmail.com>
AI disclosure: OpenAI-powered dot prepared this implementation and regression verification. This commit is part of the user-reviewed patch for issue LargeModGames#736.

Signed-off-by: 점[dot] <jum.apzn@gmail.com>
AI disclosure: OpenAI-powered dot prepared these regression tests and ran the verification reported in the pull request. This is the user-reviewed patch for issue LargeModGames#736.

Signed-off-by: 점[dot] <jum.apzn@gmail.com>
AI disclosure: OpenAI-powered dot prepared this changelog entry as part of the user-reviewed patch for issue LargeModGames#736.

Signed-off-by: 점[dot] <jum.apzn@gmail.com>
AI disclosure: OpenAI-powered dot restored the newline from the user-reviewed patch after browser entry. No behavioral change.

Signed-off-by: 점[dot] <jum.apzn@gmail.com>
@coderabbitai

coderabbitai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: LargeModGames/spotatui/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 43cc6e6d-280b-4f36-954f-0b0696bce86d

📥 Commits

Reviewing files that changed from the base of the PR and between e819b1c and 95e4836.


📒 Files selected for processing (1)
  • CHANGELOG.md

🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.md

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.



📝 Walkthrough

Walkthrough

Lua snapshot values now represent missing optional fields as nil. JSON decoding and plugin storage retain their existing null sentinel.

Changes

Lua snapshot serialization

Layer / File(s) Summary
Convert missing snapshot values to nil
src/infra/scripting/engine.rs, src/infra/scripting/api.rs, src/infra/scripting/tests.rs, CHANGELOG.md
Playback and other snapshot values use snapshot_to_lua, which serializes None as Lua nil. Tests check missing values in playback, current-track, and event playback. The changelog records the change.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium


Merge Risk: ⚪ Minimal · up to 95e48

No actionable merge-blocking concern is established for the reviewed change.

Pre-merge checks | Passed 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title uses the valid conventional-commit prefix "fix(scripting):" and concisely describes the main change. The subject is imperative.
Linked Issues check Passed Issue #736 requires absent optional fields to reach Lua as nil in synchronous reads, event playback payloads, and asynchronous data reads. The current changes route the snapshot paths through `snaps…
Out of Scope Changes check Passed The reviewed changes stay within Issue #736. They add the requested serializer helper, update the requested snapshot call sites, add regression tests, and add the changelog entry. The available change…

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

✨ Simplify code
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Oct 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 64.00000% with 9 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/infra/scripting/engine.rs 60.0% 6 Missing ⚠️
src/infra/scripting/api.rs 70.0% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

@LargeModGames

Copy link
Copy Markdown
Owner

@all-contributors please add @jum-apzn for code

@allcontributors

Copy link
Copy Markdown
Contributor

@LargeModGames

I've put up a pull request to add @jum-apzn! 🎉

@LargeModGames

Copy link
Copy Markdown
Owner

This conflicts with main in CHANGELOG.md only: #739 landed its entry on the same line as yours. Keep both entries. Can you merge main, or tick "Allow edits by maintainers" so I can fix it from here?

Signed-off-by: 점[dot] <jum.apzn@gmail.com>
@LargeModGames

Copy link
Copy Markdown
Owner

Thanks for the merge. #744 landed right after and hit the same CHANGELOG.md line, sorry about that. Can you merge main once more and keep both entries? I'll merge this one next. Ticking "Allow edits by maintainers" would let me fix the next one myself.

Signed-off-by: 점[dot] <jum.apzn@gmail.com>
@LargeModGames
LargeModGames merged commit 0f0d3a3 into LargeModGames:main Oct 11, 2026
30 checks passed
LargeModGames added a commit that referenced this pull request Oct 11, 2026
Adds @jum-apzn as a contributor for code.

This was requested by LargeModGames [in this
comment](#740 (comment))

[skip ci]

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
Co-authored-by: LargeModGames <84450916+LargeModGames@users.noreply.github.com>
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.

Lua plugins get a truthy null value, not nil, for empty fields

2 participants