serde_json для универсальных типов

#rust #serde

Вопрос:

Вот ссылка на код. Я хотел бы, чтобы Bar мог обернуть произвольный тип, который реализует сериализацию, сериализацию для json.

Может кто — нибудь поделиться, как это скомпилировать?

https://play.rust-lang.org/?version=stableamp;mode=debugamp;edition=2018amp;gist=23c8953a5649d7a00e51f2a59fbd7df7

 use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Foo {
    i: u32,
}

#[derive(Serialize, Deserialize)]
struct Bar<'a, K> where 
    K: Serialize   Deserialize<'a>
{
    f: K,
}

fn main() {
    let bf = Bar::<'_, Foo> {
        f: Foo { i: 9 },
    };
}
 
    Compiling playground v0.0.1 (/playground)
error[E0392]: parameter `'a` is never used
 --> src/lib.rs:9:12
  |
9 | struct Bar<'a, K> where 
  |            ^^ unused parameter
  |
  = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`

error[E0283]: type annotations needed
   --> src/lib.rs:10:20
    |
10  |     K: Serialize   Deserialize<'a>
    |                    ^^^^^^^^^^^^^^^ cannot infer type for type parameter `K`
    | 
   ::: /playground/.cargo/registry/src/github.com-1ecc6299db9ec823/serde-1.0.127/src/de/mod.rs:530:1
    |
530 | pub trait Deserialize<'de>: Sized {
    | --------------------------------- required by this bound in `Deserialize`
    |
    = note: cannot satisfy `K: Deserialize<'a>`

error[E0283]: type annotations needed
  --> src/lib.rs:8:21
   |
8  | #[derive(Serialize, Deserialize)]
   |                     ^^^^^^^^^^^ cannot infer type for type parameter `K`
9  | struct Bar<'a, K> where 
   |        --- required by a bound in this
10 |     K: Serialize   Deserialize<'a>
   |                    --------------- required by this bound in `Bar`
   |
   = note: cannot satisfy `K: Deserialize<'a>`
   = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider specifying the type arguments in the function call
   |
8  | #[derive(Serialize, Deserialize::<'a, K>)]
   |                                ^^^^^^^^^

error[E0283]: type annotations needed
 --> src/lib.rs:8:21
  |
8 | #[derive(Serialize, Deserialize)]
  |                     ^^^^^^^^^^^ cannot infer type for type parameter `K`
  |
  = note: cannot satisfy `K: Deserialize<'_>`
note: required because of the requirements on the impl of `Visitor<'de>` for `_::<impl Deserialize<'de> for Bar<'a, K>>::deserialize::__Visitor<'de, 'a, K>`
 --> src/lib.rs:8:21
  |
8 | #[derive(Serialize, Deserialize)]
  |                     ^^^^^^^^^^^
  = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0283, E0392.
For more information about an error, try `rustc --explain E0283`.
error: could not compile `playground`

To learn more, run the command again with --verbose.
 

Комментарии:

1. На игровой площадке Rust я получаю совершенно другую ошибку, устраняемую добавлением _a: std::marker::PhantomData, сразу после f: Foo { i: 9 }, этого . Надеюсь, это поможет.

Ответ №1:

Вам просто нужно вывести Serialize и Deserialize для вашей структуры-оболочки. Именно K поэтому их тоже следует внедрять.

 use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Foo {
    i: u32,
}

#[derive(Serialize, Deserialize)]
struct Bar<K>
{
    f: K,
}

fn main() {
    let bf = Bar::<Foo> {
        f: Foo { i: 9 },
    };
}
 

Игровая площадка

Комментарии:

1. Эй, я просто пытаюсь понять больше жизней. Что бы здесь можно было сделать: play.rust-lang.org/…

2. @NjugunaMureithi, вы не можете десериализоваться в ссылочный iirc. Кто является владельцем десериализованного объекта?

3. Да, вы правы!