Using postcard with serde

Hi, I am trying to use serde with postcard to serialize and deserialze structs. But I am getting an error type annotations needed for heapless::vec::Vec<u8, _> when calling postcard::to_vec.

use postcard;

struct Test {
  field1: i32,
  field2: i32
}

fn serialize() {
  let data = Test { field1: 10, field2: 10 };
  let output = postcard::to_vec(&data).unwrap; // error: type annotations needed for heapless::vec::Vec<u8, _>
  println!("serialized {:?}", output);
  let out = postcard::from_bytes(output.deref());
  println!("serialized {:?}", output);
}

According to postcard documentation use heapless::Vec should do it, but postcard does not expose it and installing healpless as a separate dependency gives mismatched error when I use it.

I tried postcard with use-std feature it does not work

cargo check details:

error[E0284]: type annotations needed for `heapless::vec::Vec<u8, _>`
   --> src/bin_codec/encode.rs:15:9
    |
15  |     let output= postcard::to_vec(transit_packet).unwrap();
    |         ^^^^^^  -------------------------------- type must be known at this point
    |
note: required by a const generic parameter in `to_vec`
   --> /Users/machine/.cargo/registry/src/index.crates.io-6f17d22bba15001f/postcard-1.1.1/src/ser/mod.rs:154:18
    |
154 | pub fn to_vec<T, const B: usize>(value: &T) -> Result<Vec<u8, B>>
    |                  ^^^^^^^^^^^^^^ required by this const generic parameter in `to_vec`
help: consider giving `output` an explicit type, where the value of const parameter `B` is specified
    |
15  |     let output: heapless::vec::Vec<u8, B>= postcard::to_vec(transit_packet).unwrap();
    |               +++++++++++++++++++++++++++

error[E0284]: type annotations needed for `heapless::vec::Vec<u8, _>`
  --> src/bin_codec/encode.rs:15:9
   |
15 |     let output= postcard::to_vec(transit_packet).unwrap();
   |         ^^^^^^
16 |     println!("serialized {:?}", output);
17 |     let out = postcard::from_bytes(output.deref()).unwrap();
   |                                           ----- type must be known at this point
   |
   = note: required for `heapless::vec::Vec<u8, _>` to implement `Deref`
help: consider giving `output` an explicit type, where the value of const parameter `B` is specified
   |
15 |     let output: heapless::vec::Vec<u8, B>= postcard::to_vec(transit_packet).unwrap();
   |               +++++++++++++++++++++++++++

error[E0284]: type annotations needed for `heapless::vec::Vec<u8, _>`
   --> src/bin_codec/encode.rs:15:9
    |
15  |     let output= postcard::to_vec(transit_packet).unwrap();
    |         ^^^^^^
16  |     println!("serialized {:?}", output);
    |                          ---- type must be known at this point
    |
    = note: required for `heapless::vec::Vec<u8, _>` to implement `Debug`
note: required by a bound in `core::fmt::rt::Argument::<'a>::new_debug`
   --> /Users/machine/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/fmt/rt.rs:117:29
    |
117 |     pub fn new_debug<'b, T: Debug>(x: &'b T) -> Argument<'b> {
    |                             ^^^^^ required by this bound in `Argument::<'a>::new_debug`
help: consider giving `output` an explicit type, where the value of const parameter `B` is specified
    |
15  |     let output: heapless::vec::Vec<u8, B>= postcard::to_vec(transit_packet).unwrap();
    |               +++++++++++++++++++++++++++


Please post the full text of the error as output by the cargo check command, including all notes and source code snippets. This will help us understand the problem.

updated the post

Try doing this:

+ use heapless::Vec;

- let output = postcard::to_vec(&data).unwrap;
+ let output: Vec<u8, 32> = postcard::to_vec(&data).unwrap;

Yes, that's exactly what I did to fix it. Thanks.

I am getting a new error at
let out = postcard::from_bytes(output.deref()).unwrap();
Error:

cannot satisfy `_: Deserialize<'_>`
the following types implement trait `Deserialize<'de>`:```

I have derived the `Serialize` and `Deserialize` traits on `Test`.

Any idea about it?

You also need to hint the compiler on what type you are trying to deserialize into:

let out: Test = postcard::from_bytes(output.deref()).unwrap();

Thanks for answering a trivial question, I'm new to rust

1 Like

No worries. Welcome!