Comments (6)
Hi, thanks for the interest in this project. The function fits the scope of this project and could be added.
However, it seems your example does not what you intend it to do:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=bec97a5a7ea17fc21ba46af3e80d1453
Do you have another use-case for this function or an alternative implementation?
from serde_with.
The function does work as expected. I'm not sure I understand what you are trying to do in the playground example. If you are trying to deserialize a list of strings, you don't need deserialize_ignore_any at all. It is helpful in cases like this, for example: RReverser/serde-xml-rs#55 (comment)
from serde_with.
#[serde(other)]
declares an enum variant as fallback. "Ba"
does not deserialize to any enum variant so in the playground it falls back to Other
. However, if I add the deserialize_with
attribute I get this error while deserializing: Err(Error("invalid type: unit variant, expected newtype variant", line: 0, column: 0))
. The code deserializes the correct enum variant if you change "Ba"
to "Foo"
, "Bar"
, or "Baz"
.
I will check the serde-xml link later.
from serde_with.
Ok, I understand what you were trying to do. Indeed, deserialize_ignore_any does not work in that case, because deserialize_with
hints serde that you are trying to deserialize the contents of the enum variant, and the string is the enum variant, but does not have any contents. If you want an example where using deserialize_ignore_any may be useful in serde_json, you can add #[serde(untagged)]
to your enum, and remove #[serde(other)]
:
use serde::*;
fn main() {
println!("{:?}", serde_json::from_str::<Vec<Item>>(r#"[{"y":1}, {"x":1}]"#));
}
#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum Item {
Foo{x: u8},
#[serde(deserialize_with = "deserialize_ignore_any")]
Other,
}
fn deserialize_ignore_any<'de, D: Deserializer<'de>, T:Default>(deserializer: D) -> Result<T, D::Error> {
serde::de::IgnoredAny::deserialize(deserializer).map(|_| T::default())
}
from serde_with.
Ok I think I understand now how this can be used.
- It enabled the other variant in an enum (tagged with
#[serde(other)]
to consume data without failing the deserialization. This "breaks" deserialization of data-less enums (the"Ba"
example above). - You can create an other-like enum variant in an
untagged
enum, which does not allow the#[serde(other)]
attribute. It behaves similar toOther(serde::de::IgnoredAny)
, but without the downside of including theIgnoredAny
type.
@lovasoa Do you want to create a pull request to add the method? It probably fits best in src/rust.rs
.
Is it possible to extend the method to support enums with and without data? Basically supporting this without any errors during deserialization.
use serde::*;
fn main() {
println!("{:?}", serde_json::from_str::<Vec<Item>>(r#"[{"NotFoo": {"y":1}}, {"Foo": {"x":1}}, "NotBar", "Bar"]"#));
}
#[derive(Debug, Deserialize)]
enum Item {
Bar,
Foo{x: u8},
#[serde(other)]
#[serde(deserialize_with = "deserialize_ignore_any")]
Other,
}
fn deserialize_ignore_any<'de, D: Deserializer<'de>, T:Default>(deserializer: D) -> Result<T, D::Error> {
serde::de::IgnoredAny::deserialize(deserializer).map(|_| T::default())
}
from serde_with.
Is it possible to extend the method to support enums with and without data?
I don't think so, no. Serde will not even call the method when deserializing a string value for the enum. It will see that the code is expecting contents inside the enum variant, and that the data doesn't have it. What you can do in this case is :
#[derive(Debug, Deserialize)]
enum Item {
Bar,
Foo{x: u8},
}
#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum ItemContainer {
Item(Item),
#[serde(deserialize_with = "deserialize_ignore_any")]
Other,
}
I do admit that the usefulness is more limited with serde_json than with, for instance, serde-xml-rs, where #[serde(other, deserialize_with = "deserialize_ignore_any")]
is the only way of parsing a heterogeneous collection without knowing the shape of all objects in the collection.
from serde_with.
Related Issues (20)
- Feature request: per-container prefix HOT 3
- Documentation Request: how to implement `SerializeAs`/`DeserializeAs` for generic structs HOT 1
- serde_as has no effect in actix context HOT 1
- DeserializeFromStr shold accept () as Err HOT 1
- Using serde_as with tuple structs HOT 1
- apply doesn't compose with serde_as HOT 2
- Question about minimum serde version HOT 6
- Serialize enum without tags HOT 2
- [usage question] Using DurationSeconds in a hashmap HOT 1
- Consider custom/aliased Option-like enums with `skip_serializing_none` HOT 7
- unable to use chrono::DateTime<Utc> HOT 1
- RUSTSEC-2023-0075: Unaligned write of u64 on 32-bit and 16-bit platforms
- Support for serde_as attached to a struct decl (not a field) - multi-field struct with canonical representation via a primitive (e.g. String) HOT 3
- Bug? DisplayFromStr does not use FromStr and accepts invalid values - protected agains inside of impl of FromStr, attached demo HOT 2
- gate `serde_as` behind `is_human_readable` HOT 2
- [Feature request] Deserialization that only uses `FromStr` as a fallback HOT 3
- Feature Request: DurationMinutes
- Bool from anything HOT 1
- VecSkipError fails on tagged enum HOT 3
- Unable to use `serde_with::serde_as` in conjunction with `schemars(schema_with)` HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from serde_with.