Skip to content

fix: quote non-ASCII characters in pantry TOML keys#313

Merged
dubadub merged 1 commit intomainfrom
fix/pantry-non-ascii-characters
Apr 7, 2026
Merged

fix: quote non-ASCII characters in pantry TOML keys#313
dubadub merged 1 commit intomainfrom
fix/pantry-non-ascii-characters

Conversation

@dubadub
Copy link
Copy Markdown
Member

@dubadub dubadub commented Apr 6, 2026

Summary

Fixes #311

cooklang-rs changes (cooklang/cooklang-rs@d12d03c)

  • Added pantry::to_toml_string() using toml_edit for proper TOML serialization (handles non-ASCII keys, inline tables, general items)
  • PantryConf.sections changed from BTreeMap to IndexMap to preserve file order
  • Enabled toml's preserve_order feature so item order within sections is preserved
  • Updated pantry::write() to use the new serializer

CookCLI changes

  • Replaced all hand-rolled TOML serialization with cooklang::pantry::to_toml_string()
  • Removed toml_edit as a direct dependency (now handled by the parser library)
  • Removed ~120 lines of duplicated serialization code from src/pantry.rs and src/server/handlers/pantry.rs
  • Uses shift_remove instead of deprecated remove for IndexMap compatibility

Test plan

  • All 50 pantry tests pass
  • All other tests pass
  • clippy clean
  • New tests:
    • test_pantry_general_items_stay_top_level — general items stay at top level, no [general] header
    • test_pantry_item_order_preserved — item order within sections survives round-trip
    • test_pantry_section_order_preserved — section order survives round-trip
    • test_pantry_non_ascii_round_trip — Swedish characters (smörgås, äpple) round-trip correctly

@dubadub dubadub force-pushed the fix/pantry-non-ascii-characters branch 2 times, most recently from 0eee62e to 78f0881 Compare April 6, 2026 19:50
@cooklang cooklang deleted a comment from claude bot Apr 6, 2026
@cooklang cooklang deleted a comment from claude bot Apr 6, 2026
@dubadub dubadub force-pushed the fix/pantry-non-ascii-characters branch from 78f0881 to dc43774 Compare April 6, 2026 20:03
@dubadub dubadub force-pushed the fix/pantry-non-ascii-characters branch from dc43774 to 878f0b5 Compare April 7, 2026 20:11
@cooklang cooklang deleted a comment from claude bot Apr 7, 2026
@dubadub dubadub force-pushed the fix/pantry-non-ascii-characters branch from 878f0b5 to a7d21f8 Compare April 7, 2026 20:35
Use cooklang::pantry::to_toml_string() from the parser library (v0.18.4)
for all pantry serialization, replacing the hand-rolled TOML string
formatting in both src/pantry.rs and src/server/handlers/pantry.rs.

The parser library now handles all TOML escaping correctly (including
non-ASCII characters like Swedish å, ä, ö), uses inline tables for item
attributes, and preserves section/item ordering via IndexMap.

Removes toml_edit as a direct CookCLI dependency (now handled by the
parser). Uses shift_remove for IndexMap compatibility.

Tests added for general items, section/item order preservation, and
non-ASCII round-tripping.
@dubadub dubadub force-pushed the fix/pantry-non-ascii-characters branch from a7d21f8 to e16a503 Compare April 7, 2026 20:39
@cooklang cooklang deleted a comment from claude bot Apr 7, 2026
@claude
Copy link
Copy Markdown

claude bot commented Apr 7, 2026

Code Review

This PR replaces ~120 lines of duplicated hand-rolled TOML serialization across src/pantry.rs and src/server/handlers/pantry.rs with a single call to cooklang::pantry::to_toml_string() from the upgraded cooklang v0.18.4 library. This is a solid, well-motivated refactor that fixes the non-ASCII bug (#311) while eliminating the duplication.

Strengths

  • Root-cause fix: delegating serialization to the library removes the category of bugs that come from hand-rolled TOML escaping.
  • Ordering preserved: switching PantryConf.sections to IndexMap and enabling preserve_order prevents silent reordering of a user's pantry file on every save.
  • Good test coverage: four new integration tests cover general-items top-level placement, item order, section order, and non-ASCII round-trips.
  • Net code reduction: +19 / -181 lines is a meaningful simplification.

Issues

serialize_pantry_to_regular_toml wrapper in src/server/handlers/pantry.rs

The function is now a one-liner that just calls cooklang::pantry::to_toml_string(pantry_conf). The wrapper no longer adds anything. Every call site can be replaced with the direct library call, or the function should at minimum lose its doc comment ("Serialize PantryConf to regular TOML format (not array format)"), which now describes what the library does, not what the wrapper does.

seed/config/pantry.conf format change

Items that were previously serialized as bare strings (milk = "1%l") are now always written as inline tables (milk = { quantity = "2%l" }). This is correct for freshly-serialized files, but existing user pantry files in the old string-shorthand format will be rewritten to inline-table format the first time they are mutated (add/update/remove). That is a format change users might find surprising. Since the parser still accepts both forms this is backward-compatible for reading, but a note in the changelog/release notes would be considerate.

test_pantry_non_ascii_round_trip does not verify quoted-key form

The test confirms that smörgås and äpple survive the round-trip, which is the important thing. As a minor enhancement it could also assert that the serialized .conf file contains the key wrapped in double-quotes ("smörgås") to pin down the TOML encoding, not just the displayed value.

Minor

Overall this is a well-executed fix. The issues above are minor and do not block merging.

@cooklang cooklang deleted a comment from claude bot Apr 7, 2026
@dubadub dubadub merged commit 1d3d4e5 into main Apr 7, 2026
6 checks passed
@dubadub dubadub deleted the fix/pantry-non-ascii-characters branch April 7, 2026 21:33
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.

Not possible to use characters åäö in pantry

1 participant