-
Notifications
You must be signed in to change notification settings - Fork 242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
de: consider local name only for namespaced tags in structs with $value
#736
Conversation
This updates the "not_in" check that decides whether to pass a new start tag within a struct to a $value field, to only consider the local part of a QName. It now uses the same decode_name function as the QNameDeserializer that is used for keys/fields already to ensure they stay in sync. Using the namespaced name in serde (i.e. `#[serde(rename = "ns1:tag")]`) fails with ``Custom("missing field `ns1:tag`")`` today, so this will not break existing code. Might help with tafia#347
$value
Looks like I did not enable the "serialize" feature when running tests locally and got confused by the double negative. I.e.
because the former is considered as |
5781ac4
to
745278a
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## master #736 +/- ##
==========================================
+ Coverage 61.48% 61.51% +0.03%
==========================================
Files 38 38
Lines 16213 16224 +11
==========================================
+ Hits 9968 9981 +13
+ Misses 6245 6243 -2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you test if this actually fixes #347? Add regression test into ./tests/serde-issues.rs
. Try to keep original code as much as possible to be sure that's user problem is actually solved, but instead of printing results use assertions. That test is needed only if #347 is fixed.
If your patch does not fix the error, then I would like to see a test which will demonstrate working of this fix, so it will not break in the future (you are also free to add it anyway even if regression test fit our needs).
I also interested to check how it behaves with serialization. Ideally, we should be able to deserialize serialized data. I'm not sure that this is always true now, but we strive for this. So if your patch fix that aspect, it also would be welcome to be presented in a test.
When test will demonstrate changes that was made, please add an entry to Changelog.md
with a short description of what is fixed.
@@ -23,7 +23,7 @@ macro_rules! deserialize_num { | |||
/// The method will borrow if encoding is UTF-8 compatible and `name` contains | |||
/// only UTF-8 compatible characters (usually only ASCII characters). | |||
#[inline] | |||
fn decode_name<'n>(name: QName<'n>, decoder: Decoder) -> Result<Cow<'n, str>, DeError> { | |||
pub(super) fn decode_name<'n>(name: QName<'n>, decoder: Decoder) -> Result<Cow<'n, str>, DeError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move that function to de/mod.rs
instead, so it will be available in all submodules.
Hey, thank you for the review. My case is probably closer to #212, but that was closed as a duplicate of #347. I agree that a regression test would be useful so I'll add one when I find time for it. This change doesn't do anything to fix serialization, but it tries to improve upon the current behavior of only considering the local part of a QName for deserialization. My actual case is as follows: <ns1:parent>
<ns1:field />
<ns1:one />
</ns1:parent> with the following data model #[derive(Deserialize)]
#[serde[renameAll = "camelCase")]
enum Choice {
One,
Two
}
#[derive(Deserialize)]
struct Field;
#[derive(Deserialize)]
#[serde[renameAll = "camelCase")]
struct Parent {
field: Field,
#[serde(rename = "$value")]
choice: Vec<Choice>,
} Today, this will try to find "field" as a variant in "Choice" because the With the change in this PR, it will correctly identify "field" as a key on the struct even for "ns1:field". Renaming the field to "ns1:field" via serde does not work, which I guess is what #347 is about: The I imagine that adding a toggle in |
I checked, and this PR does not solve #347, but solve #683, because it actually does the same thing as #702. Unfortunately, #683 and #347 seems to contradict each other. #347 requires to consider prefix part of a tag. Well, it should be possible to fix both issues, but this simple fix just solve the #683 case, but makes us a little more far from solving #347 (in particular, this change makes it impossible to deal with that example). I would prefer to investigate possibilities to solve both cases (#683 and #347). cc @leftmostcat |
FWIW this question sent me down a rabbit hole of "canonical" encodings of a namespaced name and/or QName into a single string in XML and whether it's appropriate to use that as a field identifier. Turns out that URI isn't the answer to that, instead the Furthermore, I think it would be wrong to use a serde field name of In my mind, #347 is more about making sure the roundtrip works without different configuration for serialization and deserialization, regardless of any particular style of All that to say: After all that reading, I still think using the local part only is the correct first step toward full namespace support. |
Yes, I agree with that.
Yes, that's what I say in my previous comment. |
In that case, would it be possible to merge this PR as-is and do improvements to namespace handling as follow ups? Right now this bug (QNameDeserializer and not_in are inconsistent) severely reduces the usability of |
Yes, I'll combine your PR and #702, add tests and changelog. I'll plan to release new version soon, maybe this weekend. Unfortunately too many job at work and Kreia in KotOR2 is so intriguing. Anyway, thanks for your work! |
Closed by #702 |
This updates the "not_in" check that decides whether to pass a new start tag within a struct to a $value field, to only consider the local part of a QName. It now uses the same decode_name function as the QNameDeserializer that is used for keys/fields already to ensure they stay in sync.
Using the namespaced name in serde (i.e.
#[serde(rename = "ns1:tag")]
) fails withCustom("missing field `ns1:tag`")
today, so this will not break existing code.Might help with #347