-
-
Notifications
You must be signed in to change notification settings - Fork 781
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
Allow struct deserialization to ignore unknown fields #44
Comments
To me it is highly desirable to allow the serde-client to learn about deserialization/serialization issues. An example I have is a client communicating to a server. The server may at some point start returning fields in its json-encoded stream that are now unknown to the client. The latter should be able to choose how to handle this. Some application might want to fail outright, others might just want to warn about the data-loss. In any case, this kind of information should not be withheld from the serde-client, as it would prevent truly safe client implementations. After all, Rust is safe and fast, in that order, so are Rust programs. Possible SolutionsOptions for the Deserialization/SerializationIt feels like a clean solution to provide an options structure to all functions that perform serialization or deserialization. That way, one can configure the operation as desired. Doing so would help other issues as well, like #65 to help configure 'pretty printing'. Special Struct FieldsMaybe one could add a struct field which is annotated with something like The obvious downside of this is that structures are artificially enlarged, and it feels like orthogonal concepts are mixed here (i.e. the struct has nothing to do with the 'serde' operation, and should not be forced to keep its results). Example#[derive(Deserialize)]
struct Foo {
x: i64,
#[serde(catch_unknown)]
__unknown_fields__: Vec<String>,
} Possible IssuesA field with the proposed custom annotation must not deserialize, nor serialize. Also it must not clash with an existing field within the 'to-be-deserialized' json data. Possibly there are other intricacies that I don't see right now. |
toml-rs does this by filling a toml structure with the left-over data. The same could be done for json and xml, since both have a |
Is there any kind of workaround at this time? For example, I have no clue how to do (b). If this is a viable approach (ignoring the performance, of course), can anyone write the code to do this? Or is there some other way to hack into the mechanism without complicating things too much? |
@kirillkh it's probably not that hard to implement directly in serde. You need to modify all the |
@oli-obk it's not immediately clear how to change this in serde, e.g. line 832 in serde_codegen/src/de.rs |
the question is whether to solve this for |
This sounds more like a patch than a work around. |
+1 for making it a default to have deserialization not fail for unmapped fields for a few reasons.
|
I'm choosing not to capture one of the bajillion fields with my http json client I'm building out at the moment and ran in to this, kind of an annoying issue for me as I'm not really interested in filling out hundreds of possible fields for what I'm doing. For now I can probably hack serde to ignore unknown, I think in the future though this probably should be a deserialization option |
^ Same here, is there currently any low boilerplate way to achieve this? |
I would really like this feature. |
+1 this would be a great add. |
I have a prototype solution to this working. It needs a few days of work before it's ready for submission. I'll hijack this issue for a mini design review:
Implementation:
Some formats might want to know we're skipping data (for example a format with length prefixes for entire maps/objects), but I'm keeping it simple for now and adding no new public API. On the one hand, I don't want to muddy up this submission by advocating that skipping unknown should be the default. On the other hand, I plan on advocating for that afterwards, and there is a small way that will affect this first round: how do I allow for potential skip_deserializing_unknown negation in the future? As far as I can see there are two alternatives:
I think I lean towards 1, and adding support for that syntax to the other boolean attrs. |
+1 @JohnHeitmann I still can think of a case where we'd want this on as the default. I realized that making it a default is kind of a breaking changing but I can't think of who would want to depend on on this behavior as a default.They'd currently be a in a very fragile state anyway. I'd rather flip the use of your utility to turn on deserialization errors when new fields are added to structures existing clients are unaware of. |
Re the name: I'd suggest simply "skip_unknown" (or similar for inverted On Wed, 6 Jan 2016, 12:11 AM doug tangren notifications@github.com wrote:
|
@JohnHeitmann is there a repo I could clone to build your changes to test it out. This gh issue is the only thing holding me back from switching all my rustc serialize deps over to serde deps so I'm excited someone is looking into a fix. |
@softprops https://github.com/JohnHeitmann/serde/tree/v0.6.x Should be in a testable state. |
This has been implemented in #201 for serde 0.7.0. |
Right now
#[derive(Deserialize)]
on structs and struct variants raises an error if it's passed an unknown field. We should add an annotation that allows users to just skip these fields.The text was updated successfully, but these errors were encountered: