Hi! I am trying to implement a field attribute for serde that works with Vec<some struct>
, [some struct; N]
, and &[some struct]
. So far I have the following code (see Rust Playground):
use serde_json;
use serde::{de, ser::SerializeSeq, Deserializer, Deserialize, Serializer, Serialize};
struct Amount(u64);
impl Amount {
fn as_u64(&self) -> u64 {
self.0
}
}
trait SerdeAmountForSlice {
fn ser_u64_slice<S: SerializeSeq>(self, s: &mut S) -> Result<(), S::Error>;
}
impl SerdeAmountForSlice for Amount {
fn ser_u64_slice<S: SerializeSeq>(self, s: &mut S) -> Result<(), S::Error> {
s.serialize_element(&self.as_u64())
}
}
mod custom {
use super::*;
pub fn serialize<A: SerdeAmountForSlice, S: Serializer>(
a_slice: &[A],
s: S,
) -> Result<S::Ok, S::Error> {
let mut seq = s.serialize_seq(Some(a_slice.len()))?;
for e in a_slice {
e.ser_u64_slice(&mut seq)?;
}
seq.end()
}
pub fn deserialize<'d, A: SerdeAmountForSlice, D: Deserializer<'d>>(
d: D,
) -> Result<&'d [A], D::Error> {
}
}
#[derive(Serialize, Deserialize)]
struct Lol<'a> {
#[serde(with = "custom")]
amt1: Vec<Amount>,
#[serde(with = "custom")]
amt2: [Amount; 1],
#[serde(with = "custom")]
amt3: &'a [Amount],
}
fn main() {
let lol = Lol {
amt1: vec![Amount(1), Amount(2)],
amt2: [Amount(3)],
amt3: &[Amount(3), Amount(4), Amount(5)],
};
}
But I am getting the following errors:
rror[E0308]: mismatched types
--> src/main.rs:36:10
|
34 | pub fn deserialize<'d, A: SerdeAmountForSlice, D: Deserializer<'d>>(
| ----------- implicitly returns `()` as its body has no tail or `return` expression
35 | d: D,
36 | ) -> Result<&'d [A], D::Error> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Result`, found `()`
|
= note: expected enum `Result<&'d [A], <D as _::_serde::Deserializer<'d>>::Error>`
found unit type `()`
error[E0308]: mismatched types
--> src/main.rs:41:21
|
41 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^- help: try using a conversion method: `.to_vec()`
| |
| expected struct `Vec`, found `&[_]`
|
= note: expected struct `Vec<Amount>`
found reference `&[_]`
= note: this error originates in the macro `try` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types
--> src/main.rs:41:21
|
41 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^ expected array of 1 element, found `&[_]`
|
= note: expected array `[Amount; 1]`
found reference `&[_]`
= note: this error originates in the macro `try` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` due to conflicting requirements
--> src/main.rs:41:21
|
41 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'de` as defined here...
--> src/main.rs:41:21
|
41 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
note: ...so that the types are compatible
--> src/main.rs:41:21
|
41 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
= note: expected `_::_serde::Deserializer<'_>`
found `_::_serde::Deserializer<'de>`
note: but, the lifetime must be valid for the lifetime `'a` as defined here...
--> src/main.rs:42:12
|
42 | struct Lol<'a> {
| ^^
note: ...so that the types are compatible
--> src/main.rs:41:21
|
41 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
= note: expected `Result<<__Visitor<'de, 'a> as Visitor<'de>>::visit_seq::__DeserializeWith<'de, 'a>, _>`
found `Result<<__Visitor<'de, 'a> as Visitor<'de>>::visit_seq::__DeserializeWith<'_, '_>, _>`
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` due to conflicting requirements
--> src/main.rs:41:21
|
41 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'de` as defined here...
--> src/main.rs:41:21
|
41 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
note: ...so that the types are compatible
--> src/main.rs:41:21
|
41 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
= note: expected `_::_serde::Deserializer<'_>`
found `_::_serde::Deserializer<'de>`
note: but, the lifetime must be valid for the lifetime `'a` as defined here...
--> src/main.rs:42:12
|
42 | struct Lol<'a> {
| ^^
note: ...so that the types are compatible
--> src/main.rs:41:21
|
41 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
= note: expected `Result<<__Visitor<'de, 'a> as Visitor<'de>>::visit_map::__DeserializeWith<'de, 'a>, _>`
found `Result<<__Visitor<'de, 'a> as Visitor<'de>>::visit_map::__DeserializeWith<'_, '_>, _>`
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
How to solve it?