Conversation
|
Codecov ReportAttention: Patch coverage is
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## master #490 +/- ##
==========================================
+ Coverage 54.16% 61.66% +7.50%
==========================================
Files 30 33 +3
Lines 12649 15343 +2694
==========================================
+ Hits 6851 9462 +2611
- Misses 5798 5881 +83
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
I might need a few days for this |
|
How does one achieve the previous behavior of enums where the enum value would be wrapped in the enum type tag? enum Wat {
Foo,
Bar,
Baz
}
struct Test {
wat: Wat,
} results in <Test>
<Foo/>
</Test> and if you add <Test>
Foo
</Test> Is the intention that we wrap the enum in a wrapper struct if we want type tags for the enum? <Test>
<Wat>Foo</Wat>
</Test> I guess this makes it consistent with the way lists are handled, and also consistent with the philosophical standpoint that enum is simply one of N possible values, and not a container. We should probably document this change, though. |
|
It appears that the mod try_enum {
use quick_xml::{de::from_str, se::to_string};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
enum WatEnum {
#[serde(rename="FOO")]
Foo,
#[serde(rename="BAR")]
Bar,
#[serde(rename="BAZ")]
Baz
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
struct Wat {
wat: WatEnum
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
struct Wat2 {
#[serde(rename="#any")]
wat: WatEnum
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
struct Wat3 {
#[serde(rename="#text")]
wat: WatEnum
}
#[test] // This fails
fn round_trip_enum_none() {
let tst = Wat { wat: WatEnum::Bar };
let data = to_string(&tst).unwrap();
println!("{:?}", &data);
let tst_again: Wat = from_str(data.as_str()).unwrap();
assert_eq!(&tst, &tst_again);
}
#[test] // This works
fn round_trip_enum_any() {
let tst = Wat2 { wat: WatEnum::Bar };
let data = to_string(&tst).unwrap();
println!("{:?}", &data);
let tst_again: Wat2 = from_str(data.as_str()).unwrap();
assert_eq!(&tst, &tst_again);
}
#[test] // this works
fn round_trip_enum_text() {
let tst = Wat3 { wat: WatEnum::Bar };
let data = to_string(&tst).unwrap();
println!("{:?}", &data);
let tst_again: Wat3 = from_str(data.as_str()).unwrap();
assert_eq!(&tst, &tst_again);
}
} |
|
Have you run benchmarks before and after? |
|
@dralley, no. The goal is to make a correct and consistent implementation first. There a no reason to worry about performance while the old implementation is just incorrect and inconsistent |
While in this PR this can be true, that is not desired behavior. This PR is just about serializer, I plan to continue work on deserializer part in next PRs. The final goal -- a consistent and composable implementation:
|
I'm not worried about performance, correctness is of course more important, it would just be good to know if it deserves some attention afterwards |
- `$text` serialized as a simple type
- `$value` serialized as an element with name that depends from value instead of key
- Text or CDATA elements deserialized as `$value` field, if that field is expected,
and as `#text` field, if not expected
- any not-listed in known fields elements deserialized as a `$value` field, if that field is expected
doc-test failures (2):
src\de\mod.rs - de (line 139)
src\de\mod.rs - de (line 36)
Co-authored-by: Daniel Alley <[email protected]>
…tafia#252 Still 2 doc-test failures
Still 2 doc-test failures
Serialization to attributes would be done only when field explicitly marked as an attribute
failures (21):
with_root::enum_::adjacently_tagged::flatten_struct
with_root::enum_::adjacently_tagged::nested_struct
with_root::enum_::adjacently_tagged::newtype
with_root::enum_::adjacently_tagged::struct_
with_root::enum_::adjacently_tagged::text
with_root::enum_::adjacently_tagged::tuple_struct
with_root::enum_::adjacently_tagged::unit
with_root::enum_::externally_tagged::nested_struct
with_root::enum_::externally_tagged::struct_
with_root::enum_::externally_tagged::text
with_root::enum_::internally_tagged::nested_struct
with_root::enum_::internally_tagged::newtype
with_root::enum_::internally_tagged::struct_
with_root::enum_::internally_tagged::text
with_root::enum_::internally_tagged::unit
with_root::enum_::untagged::nested_struct
with_root::enum_::untagged::struct_
with_root::enum_::untagged::text
with_root::nested_struct
with_root::struct_
with_root::text
This commit changes expectations from serializing primitives - they should be
wrapped in root tag
failures (53):
with_root::char_amp
with_root::char_apos
with_root::char_gt
with_root::char_lt
with_root::char_non_escaped
with_root::char_quot
with_root::char_space
with_root::enum_::adjacently_tagged::flatten_struct
with_root::enum_::adjacently_tagged::nested_struct
with_root::enum_::adjacently_tagged::newtype
with_root::enum_::adjacently_tagged::struct_
with_root::enum_::adjacently_tagged::text
with_root::enum_::adjacently_tagged::tuple_struct
with_root::enum_::adjacently_tagged::unit
with_root::enum_::externally_tagged::nested_struct
with_root::enum_::externally_tagged::primitive_unit
with_root::enum_::externally_tagged::struct_
with_root::enum_::externally_tagged::text
with_root::enum_::internally_tagged::nested_struct
with_root::enum_::internally_tagged::newtype
with_root::enum_::internally_tagged::struct_
with_root::enum_::internally_tagged::text
with_root::enum_::internally_tagged::unit
with_root::enum_::untagged::nested_struct
with_root::enum_::untagged::newtype
with_root::enum_::untagged::struct_
with_root::enum_::untagged::text
with_root::enum_::untagged::unit
with_root::f32_
with_root::f64_
with_root::false_
with_root::i128_
with_root::i16_
with_root::i32_
with_root::i64_
with_root::i8_
with_root::isize_
with_root::map
with_root::nested_struct
with_root::option_some
with_root::seq
with_root::str_escaped
with_root::str_non_escaped
with_root::struct_
with_root::text
with_root::true_
with_root::u128_
with_root::u16_
with_root::u32_
with_root::u64_
with_root::u8_
with_root::unit
with_root::usize_
… specified
Now serializer tested in both modes: with and without root tag specified
failures (114):
with_root::char_amp
with_root::char_apos
with_root::char_gt
with_root::char_lt
with_root::char_non_escaped
with_root::char_quot
with_root::char_space
with_root::enum_::adjacently_tagged::empty_struct
with_root::enum_::adjacently_tagged::flatten_struct
with_root::enum_::adjacently_tagged::nested_struct
with_root::enum_::adjacently_tagged::newtype
with_root::enum_::adjacently_tagged::struct_
with_root::enum_::adjacently_tagged::text
with_root::enum_::adjacently_tagged::tuple_struct
with_root::enum_::adjacently_tagged::unit
with_root::enum_::externally_tagged::nested_struct
with_root::enum_::externally_tagged::primitive_unit
with_root::enum_::externally_tagged::struct_
with_root::enum_::externally_tagged::text
with_root::enum_::internally_tagged::empty_struct
with_root::enum_::internally_tagged::nested_struct
with_root::enum_::internally_tagged::newtype
with_root::enum_::internally_tagged::struct_
with_root::enum_::internally_tagged::text
with_root::enum_::internally_tagged::unit
with_root::enum_::untagged::nested_struct
with_root::enum_::untagged::newtype
with_root::enum_::untagged::struct_
with_root::enum_::untagged::text
with_root::enum_::untagged::unit
with_root::f32_
with_root::f64_
with_root::false_
with_root::i128_
with_root::i16_
with_root::i32_
with_root::i64_
with_root::i8_
with_root::isize_
with_root::map
with_root::nested_struct
with_root::option_some
with_root::seq
with_root::str_escaped
with_root::str_non_escaped
with_root::struct_
with_root::text
with_root::true_
with_root::u128_
with_root::u16_
with_root::u32_
with_root::u64_
with_root::u8_
with_root::unit
with_root::usize_
without_root::char_amp
without_root::char_apos
without_root::char_gt
without_root::char_lt
without_root::char_non_escaped
without_root::char_quot
without_root::char_space
without_root::enum_::adjacently_tagged::empty_struct
without_root::enum_::adjacently_tagged::flatten_struct
without_root::enum_::adjacently_tagged::nested_struct
without_root::enum_::adjacently_tagged::newtype
without_root::enum_::adjacently_tagged::struct_
without_root::enum_::adjacently_tagged::text
without_root::enum_::adjacently_tagged::tuple_struct
without_root::enum_::adjacently_tagged::unit
without_root::enum_::externally_tagged::nested_struct
without_root::enum_::externally_tagged::primitive_unit
without_root::enum_::externally_tagged::struct_
without_root::enum_::externally_tagged::text
without_root::enum_::internally_tagged::empty_struct
without_root::enum_::internally_tagged::flatten_struct
without_root::enum_::internally_tagged::nested_struct
without_root::enum_::internally_tagged::newtype
without_root::enum_::internally_tagged::struct_
without_root::enum_::internally_tagged::text
without_root::enum_::internally_tagged::unit
without_root::enum_::untagged::flatten_struct
without_root::enum_::untagged::nested_struct
without_root::enum_::untagged::newtype
without_root::enum_::untagged::struct_
without_root::enum_::untagged::text
without_root::enum_::untagged::tuple_struct
without_root::enum_::untagged::unit
without_root::f32_
without_root::f64_
without_root::false_
without_root::flatten_struct
without_root::i128_
without_root::i16_
without_root::i32_
without_root::i64_
without_root::i8_
without_root::isize_
without_root::map
without_root::nested_struct
without_root::seq
without_root::str_escaped
without_root::str_non_escaped
without_root::struct_
without_root::text
without_root::true_
without_root::tuple
without_root::u128_
without_root::u16_
without_root::u32_
without_root::u64_
without_root::u8_
without_root::unit
without_root::usize_
- serialize_bool - duplicate of `without_root::false_` and `without_root::true_` - serialize_struct - duplicate of `without_root::struct_` - serialize_struct_value_number - duplicate of `without_root::value` - serialize_struct_value_string - excess test, duplicate of previous - serialize_enum - duplicate of `without_root::enum_::externally_tagged::newtype` - serialize_a_list - non working test that replaced by `without_root::seq` - test_empty - duplicate of `without_root::empty_struct` - test_nested - duplicate of `without_root::nested_struct` Still 114 failures
failures (40):
enum_::adjacently_tagged::flatten_struct::attributes
enum_::adjacently_tagged::nested_struct::attributes
enum_::adjacently_tagged::newtype::attributes
enum_::adjacently_tagged::struct_::attributes
enum_::adjacently_tagged::unit::attributes
enum_::externally_tagged::flatten_struct::attributes
enum_::externally_tagged::nested_struct::attributes
enum_::externally_tagged::struct_::attributes
enum_::internally_tagged::flatten_struct::attributes
enum_::internally_tagged::nested_struct::attributes
enum_::internally_tagged::struct_::attributes
enum_::internally_tagged::unit::attributes
enum_::untagged::flatten_struct::attributes
enum_::untagged::nested_struct::attributes
flatten_struct::attributes
from_str_should_ignore_encoding
nested_struct::attributes
seq::fixed_name::fixed_size::list_of_struct
seq::fixed_name::variable_size::list_of_struct
seq::top_level::list_of_struct
struct_::attribute_and_element
struct_::attributes
struct_::excess_attributes
xml_schema_lists::attribute::bool_
xml_schema_lists::attribute::byte_buf
xml_schema_lists::attribute::char_
xml_schema_lists::attribute::f32_
xml_schema_lists::attribute::f64_
xml_schema_lists::attribute::i128_
xml_schema_lists::attribute::i16_
xml_schema_lists::attribute::i32_
xml_schema_lists::attribute::i64_
xml_schema_lists::attribute::i8_
xml_schema_lists::attribute::string
xml_schema_lists::attribute::u128_
xml_schema_lists::attribute::u16_
xml_schema_lists::attribute::u32_
xml_schema_lists::attribute::u64_
xml_schema_lists::attribute::u8_
xml_schema_lists::attribute::unit
|
What is |
I not exactly understand your question. Could you expand it?
Because this change is a part of future release (which I plan to make this year) you can find docs about it in the local copy after generating: $env:RUSTDOCFLAGS="--cfg docs_rs"; cargo +nightly doc --all-features --openand go to the documentation of the You also can read documentation source here: Line 3 in e877f4f If anything is incomprehensible, feel free to ask so that we can address ambiguities before release. |
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [quick-xml](https://github.com/tafia/quick-xml) | dependencies | minor | `0.26.0` -> `0.27.1` | --- ### Release Notes <details> <summary>tafia/quick-xml</summary> ### [`v0.27.1`](https://github.com/tafia/quick-xml/blob/HEAD/Changelog.md#​0271----2022-12-28) [Compare Source](tafia/quick-xml@v0.27.0...v0.27.1) ##### Bug Fixes - [#​530]: Fix an infinite loop leading to unbounded memory consumption that occurs when skipping events on malformed XML with the `overlapped-lists` feature active. - [#​530]: Fix an error in the `Deserializer::read_to_end` when `overlapped-lists` feature is active and malformed XML is parsed [#​530]: tafia/quick-xml#530 ### [`v0.27.0`](https://github.com/tafia/quick-xml/blob/HEAD/Changelog.md#​0270----2022-12-25) [Compare Source](tafia/quick-xml@v0.26.0...v0.27.0) ##### New Features - [#​521]: Implement `Clone` for all error types. This required changing `Error::Io` to contain `Arc<std::io::Error>` instead of `std::io::Error` since `std::io::Error` does not implement `Clone`. ##### Bug Fixes - [#​490]: Ensure that serialization of map keys always produces valid XML names. In particular, that means that maps with numeric and numeric-like keys (for example, `"42"`) no longer can be serialized because [XML name] cannot start from a digit - [#​500]: Fix deserialization of top-level sequences of enums, like ```xml <?xml version="1.0" encoding="UTF-8"?> <!-- list of enum Enum { A, B, С } --> <A/> <B/> <C/> ``` - [#​514]: Fix wrong reporting `Error::EndEventMismatch` after disabling and enabling `.check_end_names` - [#​517]: Fix swapped codes for `\r` and `\n` characters when escaping them - [#​523]: Fix incorrect skipping text and CDATA content before any map-like structures in serde deserializer, like ```xml unwanted text<struct>...</struct> ``` - [#​523]: Fix incorrect handling of `xs:list`s with encoded spaces: they still act as delimiters, which is confirmed also by mature XmlBeans Java library - [#​473]: Fix a hidden requirement to enable serde's `derive` feature to get quick-xml's `serialize` feature for `edition = 2021` or `resolver = 2` crates ##### Misc Changes - [#​490]: Removed `$unflatten=` special prefix for fields for serde (de)serializer, because: - it is useless for deserializer - serializer was rewritten and does not require it anymore This prefix allowed you to serialize struct field as an XML element and now replaced by a more thoughtful system explicitly indicating that a field should be serialized as an attribute by prepending `@` character to its name - [#​490]: Removed `$primitive=` prefix. That prefix allowed you to serialize struct field as an attribute instead of an element and now replaced by a more thoughtful system explicitly indicating that a field should be serialized as an attribute by prepending `@` character to its name - [#​490]: In addition to the `$value` special name for a field a new `$text` special name was added: - `$text` is used if you want to map field to text content only. No markup is expected (but text can represent a list as defined by `xs:list` type) - `$value` is used if you want to map elements with different names to one field, that should be represented either by an `enum`, or by sequence of `enum`s (`Vec`, tuple, etc.), or by string. Use it when you want to map field to any content of the field, text or markup Refer to [documentation] for details. - [#​521]: MSRV bumped to 1.52. - [#​473]: `serde` feature that used to make some types serializable, renamed to `serde-types` - [#​528]: Added documentation for XML to `serde` mapping [#​473]: tafia/quick-xml#473 [#​490]: tafia/quick-xml#490 [#​500]: tafia/quick-xml#500 [#​514]: tafia/quick-xml#514 [#​517]: tafia/quick-xml#517 [#​521]: tafia/quick-xml#521 [#​523]: tafia/quick-xml#523 [#​528]: tafia/quick-xml#528 [XML name]: https://www.w3.org/TR/xml11/#NT-Name [documentation]: https://docs.rs/quick-xml/0.27.0/quick_xml/de/index.html#difference-between-text-and-value-special-names </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC43My4wIiwidXBkYXRlZEluVmVyIjoiMzQuNzQuMiJ9--> Co-authored-by: cabr2-bot <[email protected]> Co-authored-by: crapStone <[email protected]> Reviewed-on: https://codeberg.org/Calciumdibromid/CaBr2/pulls/1692 Reviewed-by: crapStone <[email protected]> Co-authored-by: Calciumdibromid Bot <[email protected]> Co-committed-by: Calciumdibromid Bot <[email protected]>
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [quick-xml](https://github.com/tafia/quick-xml) | dependencies | minor | `0.27.1` -> `0.28.0` | --- ### Release Notes <details> <summary>tafia/quick-xml</summary> ### [`v0.28.0`](https://github.com/tafia/quick-xml/blob/HEAD/Changelog.md#​0280----2023-03-13) [Compare Source](tafia/quick-xml@v0.27.1...v0.28.0) ##### New Features - [#​541]: (De)serialize specially named `$text` enum variant in [externally tagged] enums to / from textual content - [#​556]: `to_writer` and `to_string` now accept `?Sized` types - [#​556]: Add new `to_writer_with_root` and `to_string_with_root` helper functions - [#​520]: Add methods `BytesText::inplace_trim_start` and `BytesText::inplace_trim_end` to trim leading and trailing spaces from text events - [#​565]: Allow deserialize special field names `$value` and `$text` into borrowed fields when use serde deserializer - [#​568]: Rename `Writter::inner` into `Writter::get_mut` - [#​568]: Add method `Writter::get_ref` - [#​569]: Rewrite the `Reader::read_event_into_async` as an async fn, making the future `Send` if possible. - [#​571]: Borrow element names (`<element>`) when deserialize with serde. This change allow to deserialize into `HashMap<&str, T>`, for example - [#​573]: Add basic support for async byte writers via tokio's `AsyncWrite`. ##### Bug Fixes - [#​537]: Restore ability to deserialize attributes that represents XML namespace mappings (`xmlns:xxx`) that was broken since [#​490] - [#​510]: Fix an error of deserialization of `Option<T>` fields where `T` is some sequence type (for example, `Vec` or tuple) - [#​540]: Fix a compilation error (probably a rustc bug) in some circumstances. `Serializer::new` and `Serializer::with_root` now accepts only references to `Write`r. - [#​520]: Merge consequent (delimited only by comments and processing instructions) texts and CDATA when deserialize using serde deserializer. `DeEvent::Text` and `DeEvent::CData` events was replaced by `DeEvent::Text` with merged content. The same behavior for the `Reader` does not implemented (yet?) and should be implemented manually - [#​562]: Correctly set minimum required version of memchr dependency to 2.1 - [#​565]: Correctly set minimum required version of tokio dependency to 1.10 - [#​565]: Fix compilation error when build with serde <1.0.139 [externally tagged]: https://serde.rs/enum-representations.html#externally-tagged [#​490]: tafia/quick-xml#490 [#​510]: tafia/quick-xml#510 [#​520]: tafia/quick-xml#520 [#​537]: tafia/quick-xml#537 [#​540]: tafia/quick-xml#540 [#​541]: tafia/quick-xml#541 [#​556]: tafia/quick-xml#556 [#​562]: tafia/quick-xml#562 [#​565]: tafia/quick-xml#565 [#​568]: tafia/quick-xml#568 [#​569]: tafia/quick-xml#569 [#​571]: tafia/quick-xml#571 [#​573]: tafia/quick-xml#573 </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS42LjAiLCJ1cGRhdGVkSW5WZXIiOiIzNS42LjAifQ==--> Co-authored-by: cabr2-bot <[email protected]> Co-authored-by: crapStone <[email protected]> Reviewed-on: https://codeberg.org/Calciumdibromid/CaBr2/pulls/1818 Reviewed-by: crapStone <[email protected]> Co-authored-by: Calciumdibromid Bot <[email protected]> Co-committed-by: Calciumdibromid Bot <[email protected]>
This PR rewrites serializer and fixes the following issues:
$primitive=unit variants doesn't work correctly yet #354 (but it still should be checked that it works aligned with the serializer)Notable changes:
$unflatten=prefix, as it not used anymore$primitive=prefix, as it not used anymore$valuespecial name split into two special names#textand#any#content. @dralley, please check especially, is the documentation clear about the differences?@character. Without that fields serialized as elements and can be deserialized only from elements. Deserialization from element or from attribute into one field is not possible anymore. It's a weird wish anyway