Comments (5)
From
/Into
is not the correct interface here. During serialization you only have references, so this might lead to cloning. The way you wrote the attributes you would get a TupSt<Same, Same>
, which is not really a useful struct to have.
The SerializeAs
/DeserializeAs
traits do cover that use case. With them, this can work (It doesn't currently, because Seq
is not flexible enough). It does make quite heavy use of the generics.
#[derive(serde::Serialize, serde::Deserialize)]
struct Custom<K, V> {
custom_key: K,
v: V,
}
impl<K, KAs, V, VAs> SerializeAs<(K, V)> for Custom<KAs, VAs>
where
KAs: SerializeAs<K>,
VAs: SerializeAs<V>,
{
fn serialize_as<S>((k, v): &(K, V), serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
(Custom {
custom_key: SerializeAsWrap::<K, KAs>::new(k),
v: SerializeAsWrap::<V, VAs>::new(v),
})
.serialize(serializer)
}
}
impl<'de, K, KAs, V, VAs> DeserializeAs<'de, (K, V)> for Custom<KAs, VAs>
where
KAs: DeserializeAs<'de, K>,
VAs: DeserializeAs<'de, V>,
{
fn deserialize_as<D>(deserializer: D) -> Result<(K, V), D::Error>
where
D: serde::Deserializer<'de>,
{
let c = <Custom<DeserializeAsWrap<K, KAs>, DeserializeAsWrap<V, VAs>>>::deserialize(
deserializer,
)?;
Ok((c.custom_key.into_inner(), c.v.into_inner()))
}
}
#[serde_as]
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct SM(#[serde_as(as = "Seq<Custom<_, _>>")] BTreeMap<u32, IpAddr>);
let map: BTreeMap<_, _> = vec![(1, ip), (10, ip), (200, ip2)].into_iter().collect();
is_equal(
SM(map),
expect![[r#"
[
{
"custom_key": 1,
"v": "1.2.3.4"
},
{
"custom_key": 10,
"v": "1.2.3.4"
},
{
"custom_key": 200,
"v": "255.255.255.255"
}
]"#]],
);
Is that a good enough solution?
from serde_with.
Sorry this doesn't seem works, I got error:
error[E0277]: the trait bound `serde_with::Seq<KvProxy<Same, Same>>: SerializeAs<_>` is not satisfied
--> src/model/manifest.rs:245:24
|
244 | / #[serde_as]
245 | | #[derive(Debug, Clone, Serialize, Deserialize)]
| | ^^^^^^^^-
| |________________________|_______|
| | required by a bound introduced by this call
| the trait `SerializeAs<_>` is not implemented for `serde_with::Seq<KvProxy<Same, Same>>`
|
= help: the following other types implement trait `SerializeAs<T>`:
<serde_with::Seq<(KAs, VAs)> as SerializeAs<BTreeMap<K, V>>>
<serde_with::Seq<(KAs, VAs)> as SerializeAs<HashMap<K, V>>>
= note: required for `DefaultOnNull<serde_with::Seq<KvProxy<Same, Same>>>` to implement `SerializeAs<_>`
note: required by a bound in `serde_with::ser::<impl As<T>>::serialize`
--> /home/cl/.cargo/registry/src/github.com-1ecc6299db9ec823/serde_with-2.2.0/src/ser/mod.rs:166:12
|
166 | T: SerializeAs<I>,
| ^^^^^^^^^^^^^^ required by this bound in `serde_with::ser::<impl As<T>>::serialize`
= note: this error originates in the derive macro `Serialize` (in Nightly builds, run with -Z macro-backtrace for more info)
Looks like SerializeAs<BTreeMap<K,V>, Seq<KvProxy<KAs, VAs>>>
cannot be deduced.
--- code ---
#[derive(Clone, Debug, Serialize, Deserialize)]
/// helper struct to deserialize a custom named struct into K-V pairs in Maps
struct KvProxy<KAs, VAs> {
/// proxy typed key
key: KAs,
/// proxy typed value
value: VAs,
}
impl<K, V, KAs, VAs> SerializeAs<(K, V)> for KvProxy<KAs, VAs>
where
KAs: SerializeAs<K>,
VAs: SerializeAs<V>,
{
fn serialize_as<S>((k, v): &(K, V), serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let proxy = KvProxy {
key: SerializeAsWrap::<K, KAs>::new(k),
value: SerializeAsWrap::<V, VAs>::new(v),
};
proxy.serialize(serializer)
}
}
impl<'de, K, V, KAs, VAs> DeserializeAs<'de, (K, V)> for KvProxy<KAs, VAs>
where
KAs: DeserializeAs<'de, K>,
VAs: DeserializeAs<'de, V>,
{
fn deserialize_as<D>(deserializer: D) -> Result<(K, V), D::Error>
where
D: Deserializer<'de>,
{
let proxy = KvProxy::<DeserializeAsWrap<K, KAs>, DeserializeAsWrap<V, VAs>>::deserialize(
deserializer,
)?;
Ok((proxy.key.into_inner(), proxy.value.into_inner()))
}
}
//...
struct DataFile {
// other fields
#[serde(default)]
#[serde_as(as = "DefaultOnNull<Seq<KvProxy<_,_>>>")]
column_sizes: BTreeMap<i32, i64>,
}
from serde_with.
This still requires changes to Seq
for it to work. I said as much in my last message
With them, this can work (It doesn't currently, because
Seq
is not flexible enough).
from serde_with.
This still requires changes to
Seq
for it to work. I said as much in my last messageWith them, this can work (It doesn't currently, because
Seq
is not flexible enough).
Sorry, my mistake.
from serde_with.
This doesn't actually work. You get this error message for this code snippet. Unfortunately, it wasn't caught with the tests.
#[serde_as(as = "Seq<(_, Vec<_>)>")]
BTreeMap<usize, Vec<usize>>,
error[E0277]: the trait bound `serde_with::Seq<(serde_with::Same, std::vec::Vec<serde_with::Same>)>: serde_with::SerializeAs<_>` is not satisfied
The problem is that during serialization you never get the key or value directly, you only get references to them. That is ok for the SerializeAs
implementation of Seq
where the two types are used separately. But you cannot make a SerializeAs
which works on a (K, V)
. At best you can do a (&K, &V)
but that doesn't really work well with SerializeAs
. The SerializeAs
trait unfortunately cannot handle different amounts of references. The type and the type pattern always must match. For the snippet above: After the PR #566 it tried to match the Vec
of the type with a &Vec
in the type pattern (the thing after "as = "). So there is a mismatch in the number of references and it no longer compiles.
Ultimately, this probably means it cannot be implemented properly. As mentioned before, From
/Into
does not seem like the correct traits here either, since they would require cloning too.
This means if you want something like Seq
which supports other types, you will need to create your own type. The trait implementations are not that complicated.
from serde_with.
Related Issues (20)
- `indexmap` v2 support
- skip_serializing_none does not work on enum struct fields HOT 1
- [Feature request] Implement serde::Serialize and serde::Deserialize for serde_with::As HOT 3
- Using `TimestampMilliSeconds` to serialize `DateTime<Utc>` differs from calling `DateTime<Utc>::timestamp_millis` HOT 1
- [Help Request] Use both true/false and 0/1 as bool parameter HOT 3
- `TimestampSeconds<i64>` panics on `i64::MIN`
- Consider adding helpers for better deserialize error messages for untagged enums HOT 6
- Include support for `hashbrown` crate HOT 4
- 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
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.