Skip to content

rust-v0.2.0

@vinitkumar vinitkumar tagged this 12 Mar 16:31
* chore: bump pyo3

* fix: prevent double-escaping of XML attribute values in make_valid_xml_name

make_valid_xml_name was calling escape_xml(key) and storing the escaped
value. Later, make_attr_string would escape it again, producing output
like name="tag&name" instead of name="tag&name".

Now make_valid_xml_name operates on the raw key and lets make_attr_string
handle the single escaping pass.

Amp-Thread-ID: https://ampcode.com/threads/T-019ce197-0f45-7644-a010-590c20704f18
Co-authored-by: Amp <amp@ampcode.com>

* fix: use Python str() for float formatting to match Python output

Rust's f64::to_string() renders 1.0 as "1" while Python gives "1.0".
Since this is a drop-in replacement for the Python dicttoxml, use
obj.str() to get Python's native float representation.

Amp-Thread-ID: https://ampcode.com/threads/T-019ce197-0f45-7644-a010-590c20704f18
Co-authored-by: Amp <amp@ampcode.com>

* fix: propagate iteration errors instead of silently swallowing them

The try_iter() path used filter_map(|r| r.ok()) which silently dropped
any exceptions raised during iteration. Now uses collect::<PyResult<_>>()?
to properly propagate errors to the caller.

Amp-Thread-ID: https://ampcode.com/threads/T-019ce197-0f45-7644-a010-590c20704f18
Co-authored-by: Amp <amp@ampcode.com>

* fix: validate custom_root is a valid XML element name

Previously custom_root was written directly into XML tags without
validation, allowing arbitrary strings to produce invalid XML output.
Now raises ValueError for invalid root element names.

Amp-Thread-ID: https://ampcode.com/threads/T-019ce197-0f45-7644-a010-590c20704f18
Co-authored-by: Amp <amp@ampcode.com>

* refactor: collapse duplicate dispatch, single-buffer writes, byte-level escaping

Major restructuring of the Rust extension:

- Collapsed three identical type-dispatch chains (convert_value,
  convert_dict, convert_list) into a single write_value() function.
  Removes ~300 lines of duplicated if/else logic.

- All XML writing now appends to a single shared String buffer via
  write_value/write_dict_contents/write_list_contents instead of
  allocating intermediate Strings at every recursion level.

- Replaced char-by-char escape_xml with byte-scanning push_escaped_text
  (for text nodes, only escapes &<>) and push_escaped_attr (for
  attributes, also escapes quotes). Copies clean slices in bulk.

- Replaced format!-based wrap_cdata with push_cdata that writes
  directly to the buffer without intermediate allocations.

- Replaced to_lowercase().starts_with("xml") in is_valid_xml_name
  with eq_ignore_ascii_case to avoid allocating a lowercased copy.

- Removed unused std::fmt::Write import, added #[derive(Copy, Clone)]
  to ConvertConfig, gated helper functions behind cfg(python).

- Added tests for push_escaped_text, push_escaped_attr, push_cdata.

Amp-Thread-ID: https://ampcode.com/threads/T-019ce197-0f45-7644-a010-590c20704f18
Co-authored-by: Amp <amp@ampcode.com>

* Fix: rust clippy errors

* fix: test failures

* fix: do cargo fmt

* chore: update the version for the rust binding

* feat: update benchmark with the latest rust version

---------

Co-authored-by: Amp <amp@ampcode.com>
Assets 2
Loading